diff options
author | Tedd Hansen | 2008-02-25 19:34:38 +0000 |
---|---|---|
committer | Tedd Hansen | 2008-02-25 19:34:38 +0000 |
commit | 5739e13f5b69f6f83ecf11e21549bfe90461790c (patch) | |
tree | 02b9e54b6fbc6cf8640861cb1c7037751fb5b3a1 /OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs | |
parent | * Resolve Mantis 667 by not passing on textures with no actual data onto Text... (diff) | |
download | opensim-SC_OLD-5739e13f5b69f6f83ecf11e21549bfe90461790c.zip opensim-SC_OLD-5739e13f5b69f6f83ecf11e21549bfe90461790c.tar.gz opensim-SC_OLD-5739e13f5b69f6f83ecf11e21549bfe90461790c.tar.bz2 opensim-SC_OLD-5739e13f5b69f6f83ecf11e21549bfe90461790c.tar.xz |
Initial patch for llSensor*
llSensor, llSensorRepeat, llSensorRemove, llDetectedName, llDetectedKey, llDetectedOwner, llDetectedType, llDetectedPos, llDetectedVel, llDetectedRot
Thank you very much kinoc! :)
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs | 275 |
1 files changed, 272 insertions, 3 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs index 33c6511..5013ab8 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs | |||
@@ -31,8 +31,11 @@ using System.Collections; | |||
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Threading; | 32 | using System.Threading; |
33 | using libsecondlife; | 33 | using libsecondlife; |
34 | using Axiom.Math; | ||
34 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Modules; | 36 | using OpenSim.Region.Environment.Modules; |
37 | using OpenSim.Region.Environment.Scenes; | ||
38 | using OpenSim.Framework; | ||
36 | 39 | ||
37 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 40 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
38 | { | 41 | { |
@@ -46,6 +49,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
46 | 49 | ||
47 | private ScriptEngine m_ScriptEngine; | 50 | private ScriptEngine m_ScriptEngine; |
48 | 51 | ||
52 | public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents = | ||
53 | new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>(); | ||
54 | private Object SenseLock = new Object(); | ||
55 | |||
49 | public AsyncLSLCommandManager(ScriptEngine _ScriptEngine) | 56 | public AsyncLSLCommandManager(ScriptEngine _ScriptEngine) |
50 | { | 57 | { |
51 | m_ScriptEngine = _ScriptEngine; | 58 | m_ScriptEngine = _ScriptEngine; |
@@ -128,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
128 | CheckXMLRPCRequests(); | 135 | CheckXMLRPCRequests(); |
129 | // Check Listeners | 136 | // Check Listeners |
130 | CheckListeners(); | 137 | CheckListeners(); |
138 | // Check Sensors | ||
139 | CheckSenseRepeaterEvents(); | ||
131 | } | 140 | } |
132 | 141 | ||
133 | /// <summary> | 142 | /// <summary> |
@@ -154,6 +163,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
154 | 163 | ||
155 | xmlrpc.CancelSRDRequests(itemID); | 164 | xmlrpc.CancelSRDRequests(itemID); |
156 | 165 | ||
166 | // Remove Sensors | ||
167 | UnSetSenseRepeaterEvents(localID, itemID); | ||
168 | |||
157 | } | 169 | } |
158 | 170 | ||
159 | #region TIMER | 171 | #region TIMER |
@@ -253,6 +265,262 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
253 | } | 265 | } |
254 | 266 | ||
255 | #endregion | 267 | #endregion |
268 | #region SENSOR | ||
269 | |||
270 | // | ||
271 | // SenseRepeater and Sensors | ||
272 | // | ||
273 | private class SenseRepeatClass | ||
274 | { | ||
275 | public uint localID; | ||
276 | public LLUUID itemID; | ||
277 | public double interval; | ||
278 | public DateTime next; | ||
279 | |||
280 | public string name; | ||
281 | public LLUUID keyID; | ||
282 | public int type; | ||
283 | public double range; | ||
284 | public double arc; | ||
285 | public SceneObjectPart host; | ||
286 | } | ||
287 | |||
288 | private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>(); | ||
289 | private object SenseRepeatListLock = new object(); | ||
290 | |||
291 | public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID, | ||
292 | string name, LLUUID keyID, int type, double range, double arc, double sec,SceneObjectPart host) | ||
293 | { | ||
294 | Console.WriteLine("SetSensorEvent"); | ||
295 | |||
296 | // Always remove first, in case this is a re-set | ||
297 | UnSetSenseRepeaterEvents(m_localID, m_itemID); | ||
298 | if (sec == 0) // Disabling timer | ||
299 | return; | ||
300 | |||
301 | // Add to timer | ||
302 | SenseRepeatClass ts = new SenseRepeatClass(); | ||
303 | ts.localID = m_localID; | ||
304 | ts.itemID = m_itemID; | ||
305 | ts.interval = sec; | ||
306 | ts.name = name; | ||
307 | ts.keyID = keyID; | ||
308 | ts.type = type; | ||
309 | ts.range = range; | ||
310 | ts.arc = arc; | ||
311 | ts.host = host; | ||
312 | |||
313 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); | ||
314 | lock (SenseRepeatListLock) | ||
315 | { | ||
316 | SenseRepeaters.Add(ts); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID) | ||
321 | { | ||
322 | // Remove from timer | ||
323 | lock (SenseRepeatListLock) | ||
324 | { | ||
325 | List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>(); | ||
326 | foreach (SenseRepeatClass ts in SenseRepeaters) | ||
327 | { | ||
328 | if (ts.localID != m_localID && ts.itemID != m_itemID) | ||
329 | { | ||
330 | NewSensors.Add(ts); | ||
331 | } | ||
332 | } | ||
333 | SenseRepeaters.Clear(); | ||
334 | SenseRepeaters = NewSensors; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | public void CheckSenseRepeaterEvents() | ||
339 | { | ||
340 | // Nothing to do here? | ||
341 | if (SenseRepeaters.Count == 0) | ||
342 | return; | ||
343 | |||
344 | lock (SenseRepeatListLock) | ||
345 | { | ||
346 | // Go through all timers | ||
347 | foreach (SenseRepeatClass ts in SenseRepeaters) | ||
348 | { | ||
349 | // Time has passed? | ||
350 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) | ||
351 | { | ||
352 | SensorSweep(ts); | ||
353 | // set next interval | ||
354 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); | ||
355 | } | ||
356 | } | ||
357 | } // lock | ||
358 | } | ||
359 | |||
360 | public void SenseOnce(uint m_localID, LLUUID m_itemID, | ||
361 | string name, LLUUID keyID, int type, double range, double arc, SceneObjectPart host) | ||
362 | { | ||
363 | // Add to timer | ||
364 | SenseRepeatClass ts = new SenseRepeatClass(); | ||
365 | ts.localID = m_localID; | ||
366 | ts.itemID = m_itemID; | ||
367 | ts.interval = 0; | ||
368 | ts.name = name; | ||
369 | ts.keyID = keyID; | ||
370 | ts.type = type; | ||
371 | ts.range = range; | ||
372 | ts.arc = arc; | ||
373 | ts.host = host; | ||
374 | SensorSweep(ts); | ||
375 | } | ||
376 | |||
377 | public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID) | ||
378 | { | ||
379 | lock (SenseLock) | ||
380 | { | ||
381 | Dictionary<LLUUID, LSL_Types.list> Obj = null; | ||
382 | if (!SenseEvents.TryGetValue(m_localID, out Obj)) | ||
383 | { | ||
384 | m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID); | ||
385 | return null; | ||
386 | } | ||
387 | lock (Obj) | ||
388 | { | ||
389 | // Get script | ||
390 | LSL_Types.list SenseList = null; | ||
391 | if (!Obj.TryGetValue(m_itemID, out SenseList)) | ||
392 | { | ||
393 | m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID); | ||
394 | return null; | ||
395 | } | ||
396 | return SenseList; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | } | ||
401 | |||
402 | private void SensorSweep(SenseRepeatClass ts) | ||
403 | { | ||
404 | //m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep"); | ||
405 | SceneObjectPart SensePoint =ts.host; | ||
406 | |||
407 | if (SensePoint == null) | ||
408 | { | ||
409 | //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString()); | ||
410 | return; | ||
411 | } | ||
412 | //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan"); | ||
413 | |||
414 | LLVector3 sensorPos = SensePoint.AbsolutePosition; | ||
415 | LLVector3 regionPos = new LLVector3(m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0); | ||
416 | LLVector3 fromRegionPos = sensorPos + regionPos; | ||
417 | |||
418 | LLQuaternion q = SensePoint.RotationOffset; | ||
419 | LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); | ||
420 | LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); | ||
421 | double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); | ||
422 | |||
423 | // Here we should do some smart culling ... | ||
424 | // math seems quicker than strings so try that first | ||
425 | LSL_Types.list SensedObjects = new LSL_Types.list(); | ||
426 | LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0); | ||
427 | |||
428 | foreach (EntityBase ent in m_ScriptEngine.World.Entities.Values) | ||
429 | { | ||
430 | |||
431 | LLVector3 toRegionPos = ent.AbsolutePosition + regionPos; | ||
432 | double dis = Math.Abs((double) Util.GetDistanceTo(toRegionPos, fromRegionPos)); | ||
433 | if (dis <= ts.range) | ||
434 | { | ||
435 | // In Range, is it the right Type ? | ||
436 | int objtype = 0; | ||
437 | |||
438 | if (m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor | ||
439 | if (ent.Velocity.Equals(ZeroVector)) | ||
440 | objtype |= 0x04; // passive non-moving | ||
441 | else | ||
442 | objtype |= 0x02; // active moving | ||
443 | if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ... | ||
444 | |||
445 | if ( ((ts.type & objtype) != 0 ) ||((ts.type & objtype) == ts.type )) | ||
446 | { | ||
447 | // docs claim AGENT|ACTIVE should find agent objects OR active objects | ||
448 | // so the bitwise AND with object type should be non-zero | ||
449 | |||
450 | // Right type too, what about the other params , key and name ? | ||
451 | bool keep = true; | ||
452 | if (ts.arc != Math.PI) | ||
453 | { | ||
454 | // not omni-directional. Can you see it ? | ||
455 | // vec forward_dir = llRot2Fwd(llGetRot()) | ||
456 | // vec obj_dir = toRegionPos-fromRegionPos | ||
457 | // dot=dot(forward_dir,obj_dir) | ||
458 | // mag_fwd = mag(forward_dir) | ||
459 | // mag_obj = mag(obj_dir) | ||
460 | // ang = acos( dot /(mag_fwd*mag_obj)) | ||
461 | double ang_obj = 0; | ||
462 | try | ||
463 | { | ||
464 | LLVector3 diff =toRegionPos - fromRegionPos; | ||
465 | LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); | ||
466 | double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); | ||
467 | double mag_obj = LSL_Types.Vector3.Mag(obj_dir); | ||
468 | ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); | ||
469 | } | ||
470 | catch | ||
471 | { | ||
472 | } | ||
473 | |||
474 | if (ang_obj > ts.arc) keep = false; | ||
475 | } | ||
476 | |||
477 | if (keep && (ts.name.Length > 0) && (ts.name != ent.Name)) | ||
478 | { | ||
479 | keep = false; | ||
480 | } | ||
481 | |||
482 | if (keep && (ts.keyID != null) && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID)) | ||
483 | { | ||
484 | keep = false; | ||
485 | } | ||
486 | if (keep==true) SensedObjects.Add(ent.UUID); | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock"); | ||
491 | |||
492 | lock (SenseLock) | ||
493 | { | ||
494 | // Create object if it doesn't exist | ||
495 | if (SenseEvents.ContainsKey(ts.localID) == false) | ||
496 | { | ||
497 | SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>()); | ||
498 | } | ||
499 | // clear if previous traces exist | ||
500 | Dictionary<LLUUID, LSL_Types.list> Obj; | ||
501 | SenseEvents.TryGetValue(ts.localID, out Obj); | ||
502 | if (Obj.ContainsKey(ts.itemID) == true) | ||
503 | Obj.Remove(ts.itemID); | ||
504 | |||
505 | // note list may be zero length | ||
506 | Obj.Add(ts.itemID, SensedObjects); | ||
507 | |||
508 | if (SensedObjects.Length == 0) | ||
509 | { | ||
510 | // send a "no_sensor" | ||
511 | // Add it to queue | ||
512 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "no_sensor", EventQueueManager.llDetectNull, | ||
513 | new object[] {}); | ||
514 | } | ||
515 | else | ||
516 | { | ||
517 | |||
518 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull, | ||
519 | new object[] { SensedObjects.Length }); | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | #endregion | ||
256 | 524 | ||
257 | #region HTTP REQUEST | 525 | #region HTTP REQUEST |
258 | 526 | ||
@@ -271,7 +539,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
271 | 539 | ||
272 | while (httpInfo != null) | 540 | while (httpInfo != null) |
273 | { | 541 | { |
274 | //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status); | 542 | //m_ScriptEngine.Log.Info("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status); |
275 | 543 | ||
276 | // Deliver data to prim's remote_data handler | 544 | // Deliver data to prim's remote_data handler |
277 | // | 545 | // |
@@ -291,7 +559,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
291 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( | 559 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( |
292 | httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj | 560 | httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj |
293 | ); | 561 | ); |
294 | 562 | //Thread.Sleep(2500); | |
295 | } | 563 | } |
296 | 564 | ||
297 | httpInfo = iHttpReq.GetNextCompletedRequest(); | 565 | httpInfo = iHttpReq.GetNextCompletedRequest(); |
@@ -381,7 +649,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
381 | //Deliver data to prim's listen handler | 649 | //Deliver data to prim's listen handler |
382 | object[] resobj = new object[] | 650 | object[] resobj = new object[] |
383 | { | 651 | { |
384 | lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() | 652 | //lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() |
653 | lInfo.GetChannel(), lInfo.GetName(), lInfo.GetSourceItemID().ToString(), lInfo.GetMessage() | ||
385 | }; | 654 | }; |
386 | 655 | ||
387 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( | 656 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( |