From 2b5b2f4e60737f0a2197ff32cad4314a78671525 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 21 May 2010 21:02:26 +0100 Subject: Add a new priority scheme that works like FrontBack, but completely deprioritizes static prims, creating a hierarchy as follows: 0 == own avatar < other avatars < pysical prims < static prims For a child agent, simply acts like FrontBack --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index e6a4642..1eb0c28 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -4,6 +4,7 @@ using log4net; using Nini.Config; using OpenSim.Framework; using OpenMetaverse; +using OpenSim.Region.Physics.Manager; /* * Steps to add a new prioritization policy: @@ -25,6 +26,7 @@ namespace OpenSim.Region.Framework.Scenes Distance = 1, SimpleAngularDistance = 2, FrontBack = 3, + BestAvatarResponsiveness = 4, } public class Prioritizer @@ -50,6 +52,8 @@ namespace OpenSim.Region.Framework.Scenes return GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance case UpdatePrioritizationSchemes.FrontBack: return GetPriorityByFrontBack(client, entity); + case UpdatePrioritizationSchemes.BestAvatarResponsiveness: + return GetPriorityByBestAvatarResponsiveness(client, entity); default: throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); } @@ -130,5 +134,58 @@ namespace OpenSim.Region.Framework.Scenes return double.NaN; } + + private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) + { + ScenePresence presence = m_scene.GetScenePresence(client.AgentId); + if (presence != null) + { + // If this is an update for our own avatar give it the highest priority + if (presence == entity) + return 0.0; + + // Use group position for child prims + Vector3 entityPos = entity.AbsolutePosition; + if (entity is SceneObjectPart) + entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + else + entityPos = entity.AbsolutePosition; + + if (!presence.IsChildAgent) + { + if (entity is ScenePresence) + return 1.0; + + // Root agent. Use distance from camera and a priority decrease for objects behind us + Vector3 camPosition = presence.CameraPosition; + Vector3 camAtAxis = presence.CameraAtAxis; + + // Distance + double priority = Vector3.DistanceSquared(camPosition, entityPos); + + // Plane equation + float d = -Vector3.Dot(camPosition, camAtAxis); + float p = Vector3.Dot(camAtAxis, entityPos) + d; + if (p < 0.0f) priority *= 2.0; + + if (entity is SceneObjectPart) + { + PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + if (physActor == null || !physActor.IsPhysical) + priority+=100; + } + return priority; + } + else + { + // Child agent. Use the normal distance method + Vector3 presencePos = presence.AbsolutePosition; + + return Vector3.DistanceSquared(presencePos, entityPos); + } + } + + return double.NaN; + } } } -- cgit v1.1