aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Prioritizer.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs164
1 files changed, 132 insertions, 32 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index ae85560..53ca849 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -35,7 +35,7 @@ using OpenSim.Region.PhysicsModules.SharedBase;
35 35
36/* 36/*
37 * Steps to add a new prioritization policy: 37 * Steps to add a new prioritization policy:
38 * 38 *
39 * - Add a new value to the UpdatePrioritizationSchemes enum. 39 * - Add a new value to the UpdatePrioritizationSchemes enum.
40 * - Specify this new value in the [InterestManagement] section of your 40 * - Specify this new value in the [InterestManagement] section of your
41 * OpenSim.ini. The name in the config file must match the enum value name 41 * OpenSim.ini. The name in the config file must match the enum value name
@@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Scenes
59 public class Prioritizer 59 public class Prioritizer
60 { 60 {
61 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 61 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
62 62
63 private Scene m_scene; 63 private Scene m_scene;
64 64
65 public Prioritizer(Scene scene) 65 public Prioritizer(Scene scene)
@@ -91,9 +91,10 @@ namespace OpenSim.Region.Framework.Scenes
91 return 0; 91 return 0;
92 92
93 uint priority; 93 uint priority;
94 94
95 switch (m_scene.UpdatePrioritizationScheme) 95 switch (m_scene.UpdatePrioritizationScheme)
96 { 96 {
97/*
97 case UpdatePrioritizationSchemes.Time: 98 case UpdatePrioritizationSchemes.Time:
98 priority = GetPriorityByTime(client, entity); 99 priority = GetPriorityByTime(client, entity);
99 break; 100 break;
@@ -106,13 +107,16 @@ namespace OpenSim.Region.Framework.Scenes
106 case UpdatePrioritizationSchemes.FrontBack: 107 case UpdatePrioritizationSchemes.FrontBack:
107 priority = GetPriorityByFrontBack(client, entity); 108 priority = GetPriorityByFrontBack(client, entity);
108 break; 109 break;
110*/
111 case UpdatePrioritizationSchemes.SimpleAngularDistance:
112 priority = GetPriorityByAngularDistance(client, entity); // TODO: Reimplement SimpleAngularDistance
113 break;
109 case UpdatePrioritizationSchemes.BestAvatarResponsiveness: 114 case UpdatePrioritizationSchemes.BestAvatarResponsiveness:
115 default:
110 priority = GetPriorityByBestAvatarResponsiveness(client, entity); 116 priority = GetPriorityByBestAvatarResponsiveness(client, entity);
111 break; 117 break;
112 default:
113 throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
114 } 118 }
115 119
116 return priority; 120 return priority;
117 } 121 }
118 122
@@ -141,7 +145,7 @@ namespace OpenSim.Region.Framework.Scenes
141 145
142 return ComputeDistancePriority(client,entity,false); 146 return ComputeDistancePriority(client,entity,false);
143 } 147 }
144 148
145 private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) 149 private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
146 { 150 {
147 // And anything attached to this avatar gets top priority as well 151 // And anything attached to this avatar gets top priority as well
@@ -157,30 +161,39 @@ namespace OpenSim.Region.Framework.Scenes
157 161
158 private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) 162 private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
159 { 163 {
160 uint pqueue = ComputeDistancePriority(client,entity,true); 164 uint pqueue = 2; // keep compiler happy
161 165
162 ScenePresence presence = m_scene.GetScenePresence(client.AgentId); 166 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
163 if (presence != null) 167 if (presence != null)
164 { 168 {
165 if (!presence.IsChildAgent) 169 // All avatars other than our own go into pqueue 1
170 if (entity is ScenePresence)
171 return 1;
172
173 if (entity is SceneObjectPart)
166 { 174 {
167 // All avatars other than our own go into pqueue 1 175 SceneObjectGroup sog = ((SceneObjectPart)entity).ParentGroup;
168 if (entity is ScenePresence) 176 // Attachments are high priority,
169 return 1; 177 if (sog.IsAttachment)
178 return 2;
170 179
171 if (entity is SceneObjectPart) 180
181 if(presence.ParentPart != null)
172 { 182 {
173 // Attachments are high priority, 183 if(presence.ParentPart.ParentGroup == sog)
174 if (((SceneObjectPart)entity).ParentGroup.IsAttachment) 184 return 2;
175 return 1;
176
177 // Non physical prims are lower priority than physical prims
178 PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
179 if (physActor == null || !physActor.IsPhysical)
180 pqueue++;
181 } 185 }
186
187 pqueue = ComputeDistancePriority(client, entity, false);
188
189 // Non physical prims are lower priority than physical prims
190 PhysicsActor physActor = sog.RootPart.PhysActor;
191 if (physActor == null || !physActor.IsPhysical)
192 pqueue++;
182 } 193 }
183 } 194 }
195 else
196 pqueue = ComputeDistancePriority(client, entity, false);
184 197
185 return pqueue; 198 return pqueue;
186 } 199 }
@@ -191,7 +204,7 @@ namespace OpenSim.Region.Framework.Scenes
191 ScenePresence presence = m_scene.GetScenePresence(client.AgentId); 204 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
192 if (presence == null) 205 if (presence == null)
193 { 206 {
194 // this shouldn't happen, it basically means that we are prioritizing 207 // this shouldn't happen, it basically means that we are prioritizing
195 // updates to send to a client that doesn't have a presence in the scene 208 // updates to send to a client that doesn't have a presence in the scene
196 // seems like there's race condition here... 209 // seems like there's race condition here...
197 210
@@ -199,7 +212,7 @@ namespace OpenSim.Region.Framework.Scenes
199 // throw new InvalidOperationException("Prioritization agent not defined"); 212 // throw new InvalidOperationException("Prioritization agent not defined");
200 return PriorityQueue.NumberOfQueues - 1; 213 return PriorityQueue.NumberOfQueues - 1;
201 } 214 }
202 215
203 // Use group position for child prims, since we are putting child prims in 216 // Use group position for child prims, since we are putting child prims in
204 // the same queue with the root of the group, the root prim (which goes into 217 // the same queue with the root of the group, the root prim (which goes into
205 // the queue first) should always be sent first, no need to adjust child prim 218 // the queue first) should always be sent first, no need to adjust child prim
@@ -212,25 +225,43 @@ namespace OpenSim.Region.Framework.Scenes
212 } 225 }
213 226
214 // Use the camera position for local agents and avatar position for remote agents 227 // Use the camera position for local agents and avatar position for remote agents
215 Vector3 presencePos = (presence.IsChildAgent) ? 228 // Why would I want that? They could be camming but I still see them at the
216 presence.AbsolutePosition : 229 // avatar position, so why should I update them as if they were at their
217 presence.CameraPosition; 230 // camera positions? Makes no sense!
231 // TODO: Fix this mess
232 //Vector3 presencePos = (presence.IsChildAgent) ?
233 // presence.AbsolutePosition :
234 // presence.CameraPosition;
235
236 Vector3 presencePos = presence.AbsolutePosition;
218 237
219 // Compute the distance... 238 // Compute the distance...
220 double distance = Vector3.Distance(presencePos, entityPos); 239 double distance = Vector3.Distance(presencePos, entityPos);
221 240
222 // And convert the distance to a priority queue, this computation gives queues 241 // And convert the distance to a priority queue, this computation gives queues
223 // at 10, 20, 40, 80, 160, 320, 640, and 1280m 242 // at 10, 20, 40, 80, 160, 320, 640, and 1280m
224 uint pqueue = PriorityQueue.NumberOfImmediateQueues; 243 uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue
225 uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; 244 uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues;
226 245/*
227 for (int i = 0; i < queues - 1; i++) 246 for (int i = 0; i < queues - 1; i++)
228 { 247 {
229 if (distance < 10 * Math.Pow(2.0,i)) 248 if (distance < 30 * Math.Pow(2.0,i))
230 break; 249 break;
231 pqueue++; 250 pqueue++;
232 } 251 }
233 252*/
253 if (distance > 10f)
254 {
255 float tmp = (float)Math.Log((double)distance) * 1.442695f - 3.321928f;
256 // for a map identical to original:
257 // now
258 // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
259 // 2st constant makes it be log2(distance/10)
260 pqueue += (uint)tmp;
261 if (pqueue > queues - 1)
262 pqueue = queues - 1;
263 }
264
234 // If this is a root agent, then determine front & back 265 // If this is a root agent, then determine front & back
235 // Bump up the priority queue (drop the priority) for any objects behind the avatar 266 // Bump up the priority queue (drop the priority) for any objects behind the avatar
236 if (useFrontBack && ! presence.IsChildAgent) 267 if (useFrontBack && ! presence.IsChildAgent)
@@ -242,12 +273,81 @@ namespace OpenSim.Region.Framework.Scenes
242 // Plane equation 273 // Plane equation
243 float d = -Vector3.Dot(camPosition, camAtAxis); 274 float d = -Vector3.Dot(camPosition, camAtAxis);
244 float p = Vector3.Dot(camAtAxis, entityPos) + d; 275 float p = Vector3.Dot(camAtAxis, entityPos) + d;
245 if (p < 0.0f) 276 if (p < 0.0f)
246 pqueue++; 277 pqueue++;
247 } 278 }
248 279
249 return pqueue; 280 return pqueue;
250 } 281 }
251 282
283 private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity)
284 {
285 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
286 if (presence == null)
287 return PriorityQueue.NumberOfQueues - 1;
288
289 uint pqueue = ComputeAngleDistancePriority(presence, entity);
290 return pqueue;
291 }
292
293 private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity)
294 {
295 // And convert the distance to a priority queue, this computation gives queues
296 // at 10, 20, 40, 80, 160, 320, 640, and 1280m
297// uint minpqueue = PriorityQueue.NumberOfImmediateQueues;
298 uint maxqueue = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues -1;
299// uint pqueue = minpqueue;
300 uint pqueue = PriorityQueue.NumberOfImmediateQueues;
301 float distance;
302
303 Vector3 presencePos = presence.AbsolutePosition;
304 if(entity is ScenePresence)
305 {
306 ScenePresence sp = entity as ScenePresence;
307 distance = Vector3.Distance(presencePos, sp.AbsolutePosition);
308 distance *= 0.5f;
309 }
310 else
311 {
312 SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
313 if(presence.ParentPart != null)
314 {
315 if(presence.ParentPart.ParentGroup == group)
316 return pqueue;
317 }
318 if(group.IsAttachment)
319 {
320 if(group.RootPart.LocalId == presence.LocalId)
321 return pqueue;
322 }
323
324 float bradius = group.GetBoundsRadius();
325 Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter();
326 distance = Vector3.Distance(presencePos, grppos);
327 distance -= bradius;
328 distance *= group.getAreaFactor();
329 if(group.IsAttachment)
330 distance *= 0.5f;
331 else if(group.UsesPhysics)
332 distance *= 0.6f;
333 else if(group.GetSittingAvatarsCount() > 0)
334 distance *= 0.5f;
335 }
336
337 if (distance > 10f)
338 {
339 float tmp = (float)Math.Log(distance) * 1.442695f - 3.321928f;
340 // for a map identical to original:
341 // now
342 // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
343 // 2st constant makes it be log2(distance/10)
344
345 pqueue += (uint)tmp;
346 if (pqueue > maxqueue)
347 pqueue = maxqueue;
348 }
349
350 return pqueue;
351 }
252 } 352 }
253} 353}