aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs91
1 files changed, 69 insertions, 22 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 946765a..808d880 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -73,6 +73,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
73 public SceneObjectPart host; 73 public SceneObjectPart host;
74 } 74 }
75 75
76 //
77 // Sensed entity
78 //
79 private class SensedEntity : IComparable
80 {
81 public SensedEntity(double detectedDistance, UUID detectedID)
82 {
83 distance = detectedDistance;
84 itemID = detectedID;
85 }
86 public int CompareTo(object obj)
87 {
88 if (!(obj is SensedEntity)) throw new InvalidOperationException();
89 SensedEntity ent = (SensedEntity)obj;
90 if (ent == null || ent.distance < distance) return 1;
91 if (ent.distance > distance) return -1;
92 return 0;
93 }
94 public UUID itemID;
95 public double distance;
96 }
97
76 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>(); 98 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
77 private object SenseRepeatListLock = new object(); 99 private object SenseRepeatListLock = new object();
78 100
@@ -175,23 +197,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
175 return; 197 return;
176 } 198 }
177 199
178 LSL_Types.list SensedObjects = new LSL_Types.list(); 200 List<SensedEntity> sensedEntities = new List<SensedEntity>();
179 201
180 // Is the sensor type is AGENT and not SCRIPTED then include agents 202 // Is the sensor type is AGENT and not SCRIPTED then include agents
181 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 203 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
182 { 204 {
183 doAgentSensor(ts, SensedObjects); 205 sensedEntities.AddRange(doAgentSensor(ts));
184 } 206 }
185 207
186 // If SCRIPTED or PASSIVE or ACTIVE check objects 208 // If SCRIPTED or PASSIVE or ACTIVE check objects
187 if ((ts.type & SCRIPTED) != 0 || (ts.type & PASSIVE) != 0 || (ts.type & ACTIVE) != 0) 209 if ((ts.type & SCRIPTED) != 0 || (ts.type & PASSIVE) != 0 || (ts.type & ACTIVE) != 0)
188 { 210 {
189 doObjectSensor(ts, SensedObjects); 211 sensedEntities.AddRange(doObjectSensor(ts));
190 } 212 }
191 213
192 lock (SenseLock) 214 lock (SenseLock)
193 { 215 {
194 if (SensedObjects.Length == 0) 216 if (sensedEntities.Count == 0)
195 { 217 {
196 // send a "no_sensor" 218 // send a "no_sensor"
197 // Add it to queue 219 // Add it to queue
@@ -201,9 +223,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
201 } 223 }
202 else 224 else
203 { 225 {
204 // the sort is stride = 2 and ascending to get everything ordered by distance 226 // Sort the list to get everything ordered by distance
205 SensedObjects = SensedObjects.Sort(2, 1); 227 sensedEntities.Sort();
206 int count = SensedObjects.Length; 228 int count = sensedEntities.Count;
207 int idx; 229 int idx;
208 List<DetectParams> detected = new List<DetectParams>(); 230 List<DetectParams> detected = new List<DetectParams>();
209 for (idx = 0; idx < count; idx++) 231 for (idx = 0; idx < count; idx++)
@@ -211,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
211 try 233 try
212 { 234 {
213 DetectParams detect = new DetectParams(); 235 DetectParams detect = new DetectParams();
214 detect.Key = (UUID)(SensedObjects.Data[(idx * 2) + 1]); 236 detect.Key = sensedEntities[idx].itemID;
215 detect.Populate(m_CmdManager.m_ScriptEngine.World); 237 detect.Populate(m_CmdManager.m_ScriptEngine.World);
216 detected.Add(detect); 238 detected.Add(detect);
217 } 239 }
@@ -244,9 +266,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
244 } 266 }
245 } 267 }
246 268
247 private void doObjectSensor(SenseRepeatClass ts, LSL_Types.list SensedObjects) 269 private List<SensedEntity> doObjectSensor(SenseRepeatClass ts)
248 { 270 {
249 List<EntityBase> Entities; 271 List<EntityBase> Entities;
272 List<SensedEntity> sensedEntities = new List<SensedEntity>();
250 273
251 // If this is an object sense by key try to get it directly 274 // If this is an object sense by key try to get it directly
252 // rather than getting a list to scan through 275 // rather than getting a list to scan through
@@ -255,7 +278,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
255 EntityBase e = null; 278 EntityBase e = null;
256 m_CmdManager.m_ScriptEngine.World.Entities.TryGetValue(ts.keyID, out e); 279 m_CmdManager.m_ScriptEngine.World.Entities.TryGetValue(ts.keyID, out e);
257 if (e == null) 280 if (e == null)
258 return; 281 return sensedEntities;
259 Entities = new List<EntityBase>(); 282 Entities = new List<EntityBase>();
260 Entities.Add(e); 283 Entities.Add(e);
261 } 284 }
@@ -266,7 +289,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
266 SceneObjectPart SensePoint = ts.host; 289 SceneObjectPart SensePoint = ts.host;
267 290
268 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 291 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
292
293 // pre define some things to avoid repeated definitions in the loop body
269 Vector3 toRegionPos; 294 Vector3 toRegionPos;
295 double dis;
296 int objtype;
297 SceneObjectPart part;
298 float dx;
299 float dy;
300 float dz;
301
270 Quaternion q = SensePoint.RotationOffset; 302 Quaternion q = SensePoint.RotationOffset;
271 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 303 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
272 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 304 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
@@ -289,13 +321,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
289 if (!(ent is SceneObjectGroup)) // dont bother if it is a pesky avatar 321 if (!(ent is SceneObjectGroup)) // dont bother if it is a pesky avatar
290 continue; 322 continue;
291 toRegionPos = ent.AbsolutePosition; 323 toRegionPos = ent.AbsolutePosition;
292 double dis = Math.Abs((double)Util.GetDistanceTo(toRegionPos, fromRegionPos)); 324
325 // Calculation is in line for speed
326 dx = toRegionPos.X - fromRegionPos.X;
327 dy = toRegionPos.Y - fromRegionPos.Y;
328 dz = toRegionPos.Z - fromRegionPos.Z;
329
330 // Weed out those that will not fit in a cube the size of the range
331 // no point calculating if they are within a sphere the size of the range
332 // if they arent even in the cube
333 if (Math.Abs(dx) > ts.range || Math.Abs(dy) > ts.range || Math.Abs(dz) > ts.range)
334 dis = ts.range + 1.0;
335 else
336 dis = Math.Sqrt(dx * dx + dy * dy + dz * dz);
337
293 if (keep && dis <= ts.range && ts.host.UUID != ent.UUID) 338 if (keep && dis <= ts.range && ts.host.UUID != ent.UUID)
294 { 339 {
295 // In Range and not the object containing the script, is it the right Type ? 340 // In Range and not the object containing the script, is it the right Type ?
296 int objtype = 0; 341 objtype = 0;
297 342
298 SceneObjectPart part = ((SceneObjectGroup)ent).RootPart; 343 part = ((SceneObjectGroup)ent).RootPart;
299 if (part.AttachmentPoint != 0) // Attached so ignore 344 if (part.AttachmentPoint != 0) // Attached so ignore
300 continue; 345 continue;
301 346
@@ -347,17 +392,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
347 if (keep == true) 392 if (keep == true)
348 { 393 {
349 // add distance for sorting purposes later 394 // add distance for sorting purposes later
350 SensedObjects.Add(new LSL_Types.LSLFloat(dis)); 395 sensedEntities.Add(new SensedEntity(dis, ent.UUID));
351 SensedObjects.Add(ent.UUID);
352 } 396 }
353 } 397 }
354 } 398 }
355 } 399 }
400 return sensedEntities;
356 } 401 }
357 402
358 private void doAgentSensor(SenseRepeatClass ts, LSL_Types.list SensedObjects) 403 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
359 { 404 {
360 List<ScenePresence> Presences; 405 List<ScenePresence> Presences;
406 List<SensedEntity> sensedEntities = new List<SensedEntity>();
361 407
362 // If this is an avatar sense by key try to get them directly 408 // If this is an avatar sense by key try to get them directly
363 // rather than getting a list to scan through 409 // rather than getting a list to scan through
@@ -365,7 +411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
365 { 411 {
366 ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID); 412 ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID);
367 if (p == null) 413 if (p == null)
368 return; 414 return sensedEntities;
369 Presences = new List<ScenePresence>(); 415 Presences = new List<ScenePresence>();
370 Presences.Add(p); 416 Presences.Add(p);
371 } 417 }
@@ -376,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
376 422
377 // If nobody about quit fast 423 // If nobody about quit fast
378 if (Presences.Count == 0) 424 if (Presences.Count == 0)
379 return; 425 return sensedEntities;
380 426
381 SceneObjectPart SensePoint = ts.host; 427 SceneObjectPart SensePoint = ts.host;
382 428
@@ -390,6 +436,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
390 bool attached = (SensePoint.AttachmentPoint != 0); 436 bool attached = (SensePoint.AttachmentPoint != 0);
391 bool nameSearch = (ts.name != null && ts.name != ""); 437 bool nameSearch = (ts.name != null && ts.name != "");
392 Vector3 toRegionPos; 438 Vector3 toRegionPos;
439 double dis;
393 440
394 foreach (ScenePresence presence in Presences) 441 foreach (ScenePresence presence in Presences)
395 { 442 {
@@ -402,7 +449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
402 keep = false; 449 keep = false;
403 toRegionPos = presence.AbsolutePosition; 450 toRegionPos = presence.AbsolutePosition;
404 451
405 double dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); 452 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos));
406 453
407 // are they in range 454 // are they in range
408 if (keep && dis <= ts.range) 455 if (keep && dis <= ts.range)
@@ -452,14 +499,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
452 499
453 if (keep) // add to list with distance 500 if (keep) // add to list with distance
454 { 501 {
455 SensedObjects.Add(new LSL_Types.LSLFloat(dis)); 502 sensedEntities.Add(new SensedEntity(dis, presence.UUID));
456 SensedObjects.Add(presence.UUID);
457 } 503 }
458 504
459 // If this is a search by name and we have just found it then no more to do 505 // If this is a search by name and we have just found it then no more to do
460 if (nameSearch && ts.name == presence.Name) 506 if (nameSearch && ts.name == presence.Name)
461 return; 507 return sensedEntities;
462 } 508 }
509 return sensedEntities;
463 } 510 }
464 511
465 public Object[] GetSerializationData(UUID itemID) 512 public Object[] GetSerializationData(UUID itemID)