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);
break;
*/
case UpdatePrioritizationSchemes.SimpleAngularDistance:
priority = GetPriorityByAngularDistance(client, entity); // TODO: Reimplement SimpleAngularDistance
break;
case UpdatePrioritizationSchemes.BestAvatarResponsiveness:
default:
priority = GetPriorityByBestAvatarResponsiveness(client, entity);
@ -241,7 +244,7 @@ namespace OpenSim.Region.Framework.Scenes
*/
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:
// now
// 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
@ -269,5 +272,67 @@ namespace OpenSim.Region.Framework.Scenes
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;
}
private float m_areaFactor;
public float getAreaFactor()
{
// math is done in GetBoundsRadius();
if(m_boundsRadius == null)
GetBoundsRadius();
return m_areaFactor;
}
public float GetBoundsRadius()
{
// this may need more threading work
if(m_boundsRadius == null)
{
float res = 0;
float areaF = 0;
SceneObjectPart p;
SceneObjectPart[] parts;
float partR;
@ -1613,12 +1623,19 @@ namespace OpenSim.Region.Framework.Scenes
}
if(partR > res)
res = partR;
if(p.maxSimpleArea() > areaF)
areaF = p.maxSimpleArea();
}
if(parts.Length > 1)
{
offset /= parts.Length; // basicly geometric center
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_boundsRadius = res;
return res;

View File

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