aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs
diff options
context:
space:
mode:
authorTedd Hansen2008-02-25 20:10:17 +0000
committerTedd Hansen2008-02-25 20:10:17 +0000
commitdbb205c18160cfe031e4076ac650eb37b9613b86 (patch)
tree0b2202ddbc710755e807bed06a0e84a795ca2e20 /OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs
parenteol (diff)
downloadopensim-SC_OLD-dbb205c18160cfe031e4076ac650eb37b9613b86.zip
opensim-SC_OLD-dbb205c18160cfe031e4076ac650eb37b9613b86.tar.gz
opensim-SC_OLD-dbb205c18160cfe031e4076ac650eb37b9613b86.tar.bz2
opensim-SC_OLD-dbb205c18160cfe031e4076ac650eb37b9613b86.tar.xz
Moved AsyncCommandManager into separate classes under "plugins".
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs307
1 files changed, 304 insertions, 3 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs
index 3324bdf..edf3fde 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs
@@ -1,10 +1,311 @@
1using System; 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*/
28
29using System;
30using System.Collections;
2using System.Collections.Generic; 31using System.Collections.Generic;
3using System.Text; 32using System.Threading;
33using libsecondlife;
34using Axiom.Math;
35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Modules;
37using OpenSim.Region.Environment.Scenes;
38using OpenSim.Framework;
39using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugins;
4 40
5namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugins 41namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugins
6{ 42{
7 class SensorRepeat 43 public class SensorRepeat
8 { 44 {
45 public AsyncCommandManager m_CmdManager;
46
47 public SensorRepeat(AsyncCommandManager CmdManager)
48 {
49 m_CmdManager = CmdManager;
50 }
51
52
53 public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents =
54 new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>();
55 private Object SenseLock = new Object();
56
57 //
58 // SenseRepeater and Sensors
59 //
60 private class SenseRepeatClass
61 {
62 public uint localID;
63 public LLUUID itemID;
64 public double interval;
65 public DateTime next;
66
67 public string name;
68 public LLUUID keyID;
69 public int type;
70 public double range;
71 public double arc;
72 public SceneObjectPart host;
73 }
74
75 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
76 private object SenseRepeatListLock = new object();
77
78 public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID,
79 string name, LLUUID keyID, int type, double range, double arc, double sec, SceneObjectPart host)
80 {
81 Console.WriteLine("SetSensorEvent");
82
83 // Always remove first, in case this is a re-set
84 UnSetSenseRepeaterEvents(m_localID, m_itemID);
85 if (sec == 0) // Disabling timer
86 return;
87
88 // Add to timer
89 SenseRepeatClass ts = new SenseRepeatClass();
90 ts.localID = m_localID;
91 ts.itemID = m_itemID;
92 ts.interval = sec;
93 ts.name = name;
94 ts.keyID = keyID;
95 ts.type = type;
96 ts.range = range;
97 ts.arc = arc;
98 ts.host = host;
99
100 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
101 lock (SenseRepeatListLock)
102 {
103 SenseRepeaters.Add(ts);
104 }
105 }
106
107 public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID)
108 {
109 // Remove from timer
110 lock (SenseRepeatListLock)
111 {
112 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
113 foreach (SenseRepeatClass ts in SenseRepeaters)
114 {
115 if (ts.localID != m_localID && ts.itemID != m_itemID)
116 {
117 NewSensors.Add(ts);
118 }
119 }
120 SenseRepeaters.Clear();
121 SenseRepeaters = NewSensors;
122 }
123 }
124
125 public void CheckSenseRepeaterEvents()
126 {
127 // Nothing to do here?
128 if (SenseRepeaters.Count == 0)
129 return;
130
131 lock (SenseRepeatListLock)
132 {
133 // Go through all timers
134 foreach (SenseRepeatClass ts in SenseRepeaters)
135 {
136 // Time has passed?
137 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
138 {
139 SensorSweep(ts);
140 // set next interval
141 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
142 }
143 }
144 } // lock
145 }
146
147 public void SenseOnce(uint m_localID, LLUUID m_itemID,
148 string name, LLUUID keyID, int type, double range, double arc, SceneObjectPart host)
149 {
150 // Add to timer
151 SenseRepeatClass ts = new SenseRepeatClass();
152 ts.localID = m_localID;
153 ts.itemID = m_itemID;
154 ts.interval = 0;
155 ts.name = name;
156 ts.keyID = keyID;
157 ts.type = type;
158 ts.range = range;
159 ts.arc = arc;
160 ts.host = host;
161 SensorSweep(ts);
162 }
163
164 public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID)
165 {
166 lock (SenseLock)
167 {
168 Dictionary<LLUUID, LSL_Types.list> Obj = null;
169 if (!SenseEvents.TryGetValue(m_localID, out Obj))
170 {
171 m_CmdManager.m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID);
172 return null;
173 }
174 lock (Obj)
175 {
176 // Get script
177 LSL_Types.list SenseList = null;
178 if (!Obj.TryGetValue(m_itemID, out SenseList))
179 {
180 m_CmdManager.m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID);
181 return null;
182 }
183 return SenseList;
184 }
185 }
186
187 }
188
189 private void SensorSweep(SenseRepeatClass ts)
190 {
191 //m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep");
192 SceneObjectPart SensePoint = ts.host;
193
194 if (SensePoint == null)
195 {
196 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString());
197 return;
198 }
199 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan");
200
201 LLVector3 sensorPos = SensePoint.AbsolutePosition;
202 LLVector3 regionPos = new LLVector3(m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
203 LLVector3 fromRegionPos = sensorPos + regionPos;
204
205 LLQuaternion q = SensePoint.RotationOffset;
206 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
207 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
208 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
209
210 // Here we should do some smart culling ...
211 // math seems quicker than strings so try that first
212 LSL_Types.list SensedObjects = new LSL_Types.list();
213 LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0);
214
215 foreach (EntityBase ent in m_CmdManager.m_ScriptEngine.World.Entities.Values)
216 {
217
218 LLVector3 toRegionPos = ent.AbsolutePosition + regionPos;
219 double dis = Math.Abs((double)Util.GetDistanceTo(toRegionPos, fromRegionPos));
220 if (dis <= ts.range)
221 {
222 // In Range, is it the right Type ?
223 int objtype = 0;
224
225 if (m_CmdManager.m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor
226 if (ent.Velocity.Equals(ZeroVector))
227 objtype |= 0x04; // passive non-moving
228 else
229 objtype |= 0x02; // active moving
230 if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ...
231
232 if (((ts.type & objtype) != 0) || ((ts.type & objtype) == ts.type))
233 {
234 // docs claim AGENT|ACTIVE should find agent objects OR active objects
235 // so the bitwise AND with object type should be non-zero
236
237 // Right type too, what about the other params , key and name ?
238 bool keep = true;
239 if (ts.arc != Math.PI)
240 {
241 // not omni-directional. Can you see it ?
242 // vec forward_dir = llRot2Fwd(llGetRot())
243 // vec obj_dir = toRegionPos-fromRegionPos
244 // dot=dot(forward_dir,obj_dir)
245 // mag_fwd = mag(forward_dir)
246 // mag_obj = mag(obj_dir)
247 // ang = acos( dot /(mag_fwd*mag_obj))
248 double ang_obj = 0;
249 try
250 {
251 LLVector3 diff = toRegionPos - fromRegionPos;
252 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
253 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
254 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
255 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
256 }
257 catch
258 {
259 }
260
261 if (ang_obj > ts.arc) keep = false;
262 }
263
264 if (keep && (ts.name.Length > 0) && (ts.name != ent.Name))
265 {
266 keep = false;
267 }
268
269 if (keep && (ts.keyID != null) && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID))
270 {
271 keep = false;
272 }
273 if (keep == true) SensedObjects.Add(ent.UUID);
274 }
275 }
276 }
277 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock");
278
279 lock (SenseLock)
280 {
281 // Create object if it doesn't exist
282 if (SenseEvents.ContainsKey(ts.localID) == false)
283 {
284 SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>());
285 }
286 // clear if previous traces exist
287 Dictionary<LLUUID, LSL_Types.list> Obj;
288 SenseEvents.TryGetValue(ts.localID, out Obj);
289 if (Obj.ContainsKey(ts.itemID) == true)
290 Obj.Remove(ts.itemID);
291
292 // note list may be zero length
293 Obj.Add(ts.itemID, SensedObjects);
294
295 if (SensedObjects.Length == 0)
296 {
297 // send a "no_sensor"
298 // Add it to queue
299 m_CmdManager.m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "no_sensor", EventQueueManager.llDetectNull,
300 new object[] { });
301 }
302 else
303 {
304
305 m_CmdManager.m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull,
306 new object[] { SensedObjects.Length });
307 }
308 }
309 }
9 } 310 }
10} 311}