aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs
diff options
context:
space:
mode:
authorTeravus Ovares2008-05-30 12:27:06 +0000
committerTeravus Ovares2008-05-30 12:27:06 +0000
commit1a47ff8094ee414a47aebd310826906d89428a09 (patch)
tree0e90b3a33f43ff8617a077bb57b86d6b28e63e71 /OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs
parent* Fixed a dangling event hook that I added. (diff)
downloadopensim-SC_OLD-1a47ff8094ee414a47aebd310826906d89428a09.zip
opensim-SC_OLD-1a47ff8094ee414a47aebd310826906d89428a09.tar.gz
opensim-SC_OLD-1a47ff8094ee414a47aebd310826906d89428a09.tar.bz2
opensim-SC_OLD-1a47ff8094ee414a47aebd310826906d89428a09.tar.xz
* This is Melanie's XEngine script engine. I've not tested this real well, however, it's confirmed to compile and OpenSimulator to run successfully without this script engine active.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs391
1 files changed, 391 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs
new file mode 100644
index 0000000..5a87bb0
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandPlugins/SensorRepeat.cs
@@ -0,0 +1,391 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using libsecondlife;
31using OpenSim.Framework;
32using OpenSim.Region.Environment.Scenes;
33using OpenSim.Region.ScriptEngine.XEngine.Script;
34
35namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
36{
37 public class SensorRepeat
38 {
39 public AsyncCommandManager m_CmdManager;
40
41 public SensorRepeat(AsyncCommandManager CmdManager)
42 {
43 m_CmdManager = CmdManager;
44 }
45
46 public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents =
47 new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>();
48 private Object SenseLock = new Object();
49
50 //
51 // SenseRepeater and Sensors
52 //
53 private class SenseRepeatClass
54 {
55 public uint localID;
56 public LLUUID itemID;
57 public double interval;
58 public DateTime next;
59
60 public string name;
61 public LLUUID keyID;
62 public int type;
63 public double range;
64 public double arc;
65 public SceneObjectPart host;
66 }
67
68 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
69 private object SenseRepeatListLock = new object();
70
71 public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID,
72 string name, LLUUID keyID, int type, double range, double arc, double sec, SceneObjectPart host)
73 {
74 Console.WriteLine("SetSensorEvent");
75
76 // Always remove first, in case this is a re-set
77 UnSetSenseRepeaterEvents(m_localID, m_itemID);
78 if (sec == 0) // Disabling timer
79 return;
80
81 // Add to timer
82 SenseRepeatClass ts = new SenseRepeatClass();
83 ts.localID = m_localID;
84 ts.itemID = m_itemID;
85 ts.interval = sec;
86 ts.name = name;
87 ts.keyID = keyID;
88 ts.type = type;
89 ts.range = range;
90 ts.arc = arc;
91 ts.host = host;
92
93 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
94 lock (SenseRepeatListLock)
95 {
96 SenseRepeaters.Add(ts);
97 }
98 }
99
100 public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID)
101 {
102 // Remove from timer
103 lock (SenseRepeatListLock)
104 {
105 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
106 foreach (SenseRepeatClass ts in SenseRepeaters)
107 {
108 if (ts.localID != m_localID && ts.itemID != m_itemID)
109 {
110 NewSensors.Add(ts);
111 }
112 }
113 SenseRepeaters.Clear();
114 SenseRepeaters = NewSensors;
115 }
116 }
117
118 public void CheckSenseRepeaterEvents()
119 {
120 // Nothing to do here?
121 if (SenseRepeaters.Count == 0)
122 return;
123
124 lock (SenseRepeatListLock)
125 {
126 // Go through all timers
127 foreach (SenseRepeatClass ts in SenseRepeaters)
128 {
129 // Time has passed?
130 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
131 {
132 SensorSweep(ts);
133 // set next interval
134 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 }
136 }
137 } // lock
138 }
139
140 public void SenseOnce(uint m_localID, LLUUID m_itemID,
141 string name, LLUUID keyID, int type,
142 double range, double arc, SceneObjectPart host)
143 {
144 // Add to timer
145 SenseRepeatClass ts = new SenseRepeatClass();
146 ts.localID = m_localID;
147 ts.itemID = m_itemID;
148 ts.interval = 0;
149 ts.name = name;
150 ts.keyID = keyID;
151 ts.type = type;
152 ts.range = range;
153 ts.arc = arc;
154 ts.host = host;
155 SensorSweep(ts);
156 }
157
158 public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID)
159 {
160 lock (SenseLock)
161 {
162 Dictionary<LLUUID, LSL_Types.list> Obj = null;
163 if (!SenseEvents.TryGetValue(m_localID, out Obj))
164 {
165 m_CmdManager.m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID);
166 return null;
167 }
168 lock (Obj)
169 {
170 // Get script
171 LSL_Types.list SenseList = null;
172 if (!Obj.TryGetValue(m_itemID, out SenseList))
173 {
174 m_CmdManager.m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID);
175 return null;
176 }
177 return SenseList;
178 }
179 }
180 }
181
182 private void SensorSweep(SenseRepeatClass ts)
183 {
184 //m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep");
185 SceneObjectPart SensePoint = ts.host;
186
187 if (SensePoint == null)
188 {
189 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString());
190 return;
191 }
192 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan");
193
194 LLVector3 sensorPos = SensePoint.AbsolutePosition;
195 LLVector3 regionPos = new LLVector3(m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
196 LLVector3 fromRegionPos = sensorPos + regionPos;
197
198 LLQuaternion q = SensePoint.RotationOffset;
199 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
200 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
201 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
202
203 // Here we should do some smart culling ...
204 // math seems quicker than strings so try that first
205 LSL_Types.list SensedObjects = new LSL_Types.list();
206 LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0);
207
208 foreach (EntityBase ent in m_CmdManager.m_ScriptEngine.World.Entities.Values)
209 {
210 LLVector3 toRegionPos = ent.AbsolutePosition + regionPos;
211 double dis = Math.Abs((double)Util.GetDistanceTo(toRegionPos, fromRegionPos));
212 if (dis <= ts.range)
213 {
214 // In Range, is it the right Type ?
215 int objtype = 0;
216
217 if (m_CmdManager.m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor
218 if (ent.Velocity.Equals(ZeroVector))
219 objtype |= 0x04; // passive non-moving
220 else
221 objtype |= 0x02; // active moving
222 if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ...
223
224 if (((ts.type & objtype) != 0) || ((ts.type & objtype) == ts.type))
225 {
226 // docs claim AGENT|ACTIVE should find agent objects OR active objects
227 // so the bitwise AND with object type should be non-zero
228
229 // Right type too, what about the other params , key and name ?
230 bool keep = true;
231 if (ts.arc < Math.PI)
232 {
233 // not omni-directional. Can you see it ?
234 // vec forward_dir = llRot2Fwd(llGetRot())
235 // vec obj_dir = toRegionPos-fromRegionPos
236 // dot=dot(forward_dir,obj_dir)
237 // mag_fwd = mag(forward_dir)
238 // mag_obj = mag(obj_dir)
239 // ang = acos(dot /(mag_fwd*mag_obj))
240 double ang_obj = 0;
241 try
242 {
243 LLVector3 diff = toRegionPos - fromRegionPos;
244 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
245 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
246 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
247 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
248 }
249 catch
250 {
251 }
252
253 if (ang_obj > ts.arc) keep = false;
254 }
255
256 if (keep && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID))
257 {
258 keep = false;
259 }
260
261 if (keep && (ts.name.Length > 0))
262 {
263 string avatarname=null;
264 string objectname=null;
265 string entname =ent.Name;
266
267 // try avatar username surname
268 UserProfileData profile = m_CmdManager.m_ScriptEngine.World.CommsManager.UserService.GetUserProfile(ent.UUID);
269 if (profile != null)
270 {
271 avatarname = profile.FirstName + " " + profile.SurName;
272 }
273 // try an scene object
274 SceneObjectPart SOP = m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(ent.UUID);
275 if (SOP != null)
276 {
277 objectname = SOP.Name;
278 }
279
280 if ((ts.name != entname) && (ts.name != avatarname) && (ts.name != objectname))
281 {
282 keep = false;
283 }
284 }
285
286 if (keep == true) SensedObjects.Add(ent.UUID);
287 }
288 }
289 }
290 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock");
291
292 lock (SenseLock)
293 {
294 // Create object if it doesn't exist
295 if (SenseEvents.ContainsKey(ts.localID) == false)
296 {
297 SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>());
298 }
299 // clear if previous traces exist
300 Dictionary<LLUUID, LSL_Types.list> Obj;
301 SenseEvents.TryGetValue(ts.localID, out Obj);
302 if (Obj.ContainsKey(ts.itemID) == true)
303 Obj.Remove(ts.itemID);
304
305 // note list may be zero length
306 Obj.Add(ts.itemID, SensedObjects);
307
308 if (SensedObjects.Length == 0)
309 {
310 // send a "no_sensor"
311 // Add it to queue
312 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
313 new XEventParams("no_sensor", new Object[0],
314 new XDetectParams[0]));
315 }
316 else
317 {
318 XDetectParams[] detect =
319 new XDetectParams[SensedObjects.Length];
320
321 int idx;
322 for(idx = 0 ; idx < SensedObjects.Length; idx++)
323 {
324 detect[idx].Key=(LLUUID)(SensedObjects.Data[idx]);
325 }
326
327 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
328 new XEventParams("sensor",
329 new Object[] {
330 new LSL_Types.LSLInteger(SensedObjects.Length) },
331 detect));
332 }
333 }
334 }
335
336 public Object[] GetSerializationData(LLUUID itemID)
337 {
338 List<Object> data = new List<Object>();
339
340 foreach (SenseRepeatClass ts in SenseRepeaters)
341 {
342 if(ts.itemID == itemID)
343 {
344 data.Add(ts.interval);
345 data.Add(ts.name);
346 data.Add(ts.keyID);
347 data.Add(ts.type);
348 data.Add(ts.range);
349 data.Add(ts.arc);
350 }
351 }
352 return data.ToArray();
353 }
354
355 public void CreateFromData(uint localID, LLUUID itemID, LLUUID objectID,
356 Object[] data)
357 {
358 SceneObjectPart part =
359 m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(
360 objectID);
361
362 if(part == null)
363 return;
364
365 int idx=0;
366
367 while(idx < data.Length)
368 {
369 SenseRepeatClass ts = new SenseRepeatClass();
370
371 ts.localID = localID;
372 ts.itemID = itemID;
373
374 ts.interval = (double)data[idx];
375 ts.name = (string)data[idx+1];
376 ts.keyID = (LLUUID)data[idx+2];
377 ts.type = (int)data[idx+3];
378 ts.range = (double)data[idx+4];
379 ts.arc = (double)data[idx+5];
380 ts.host = part;
381
382 ts.next =
383 DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
384
385 SenseRepeaters.Add(ts);
386 idx += 6;
387 }
388 }
389
390 }
391}