29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Runtime.InteropServices;
34 using OpenSim.Region.PhysicsModules.SharedBase;
37 namespace OpenSim.
Region.PhysicsModule.ODE
49 protected List<ODERayCastRequest> m_PendingRequests =
new List<ODERayCastRequest>();
54 protected List<ODERayRequest> m_PendingRayRequests =
new List<ODERayRequest>();
69 private d.NearCallback nearCallback;
70 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
71 private List<ContactResult> m_contactResults =
new List<ContactResult>();
90 lock (m_PendingRequests)
93 req.callbackMethod = retMethod;
95 req.Normal = direction;
96 req.Origin = position;
98 m_PendingRequests.Add(req);
112 lock (m_PendingRequests)
115 req.callbackMethod = retMethod;
117 req.Normal = direction;
118 req.Origin = position;
121 m_PendingRayRequests.Add(req);
131 int time = System.Environment.TickCount;
132 lock (m_PendingRequests)
134 if (m_PendingRequests.Count > 0)
137 for (
int i = 0; i < reqs.Length; i++)
139 if (reqs[i].callbackMethod != null)
143 m_PendingRequests.Clear();
147 lock (m_PendingRayRequests)
149 if (m_PendingRayRequests.Count > 0)
152 for (
int i = 0; i < reqs.Length; i++)
154 if (reqs[i].callbackMethod != null)
158 m_PendingRayRequests.Clear();
162 lock (m_contactResults)
163 m_contactResults.Clear();
165 return System.Environment.TickCount - time;
177 float len = req.length;
182 IntPtr ray = d.CreateRay(m_scene.space, len);
183 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
186 d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
193 uint hitConsumerID = 0;
194 float distance = 999999999999f;
195 Vector3 closestcontact =
new Vector3(99999f, 99999f, 99999f);
196 Vector3 snormal = Vector3.Zero;
199 lock (m_contactResults)
203 if (Vector3.Distance(req.
Origin, cResult.
Pos) < Vector3.Distance(req.Origin, closestcontact))
205 closestcontact = cResult.Pos;
206 hitConsumerID = cResult.ConsumerID;
207 distance = cResult.Depth;
209 snormal = cResult.Normal;
213 m_contactResults.Clear();
218 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
225 private void RayCast(ODERayRequest req)
228 float len = req.length;
233 IntPtr ray = d.CreateRay(m_scene.space, len);
234 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
237 d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
243 lock (m_contactResults)
246 if (req.callbackMethod != null)
247 req.callbackMethod(m_contactResults);
252 private void near(IntPtr space, IntPtr g1, IntPtr g2)
255 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
261 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
263 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
272 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
274 catch (AccessViolationException)
276 m_log.Warn(
"[PHYSICS]: Unable to collide test a space");
287 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
299 count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.unmanagedSizeOf);
304 m_log.Error(
"[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
308 m_log.WarnFormat(
"[PHYSICS]: Unable to collide test an object: {0}", e.Message);
315 if (g1 != IntPtr.Zero)
316 m_scene.actor_name_map.TryGetValue(g1, out p1);
318 if (g2 != IntPtr.Zero)
319 m_scene.actor_name_map.TryGetValue(g1, out p2);
322 for (
int i = 0; i < count; i++)
330 collisionresult.ConsumerID = p1.LocalID;
331 collisionresult.Pos =
new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
332 collisionresult.Depth = contacts[i].depth;
333 collisionresult.Normal =
new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
334 contacts[i].normal.Z);
335 lock (m_contactResults)
336 m_contactResults.Add(collisionresult);
346 collisionresult.ConsumerID = p2.LocalID;
347 collisionresult.Pos =
new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
348 collisionresult.Depth = contacts[i].depth;
349 collisionresult.Normal =
new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
350 contacts[i].normal.Z);
352 lock (m_contactResults)
353 m_contactResults.Add(collisionresult);
362 internal
void Dispose()
void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
Queues a raycast
delegate void RayCallback(List< ContactResult > list)
void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
Queues a raycast
delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
RaycastCallback callbackMethod
ODERayCastRequestManager(OdeScene pScene)
RayCallback callbackMethod
Processes raycast requests as ODE is in a state to be able to do them. This ensures that it's thread ...
int ProcessQueuedRequests()
Process all queued raycast requests