diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 583 |
1 files changed, 356 insertions, 227 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 54a83c2..31757a9 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | |||
@@ -56,8 +56,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
56 | private OdeScene m_scene; | 56 | private OdeScene m_scene; |
57 | 57 | ||
58 | IntPtr ray; // the ray. we only need one for our lifetime | 58 | IntPtr ray; // the ray. we only need one for our lifetime |
59 | IntPtr Sphere; | ||
60 | IntPtr Box; | ||
61 | IntPtr Plane; | ||
59 | 62 | ||
60 | private const int ColisionContactGeomsPerTest = 5; | 63 | private int CollisionContactGeomsPerTest = 25; |
61 | private const int DefaultMaxCount = 25; | 64 | private const int DefaultMaxCount = 25; |
62 | private const int MaxTimePerCallMS = 30; | 65 | private const int MaxTimePerCallMS = 30; |
63 | 66 | ||
@@ -65,6 +68,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
65 | /// ODE near callback delegate | 68 | /// ODE near callback delegate |
66 | /// </summary> | 69 | /// </summary> |
67 | private d.NearCallback nearCallback; | 70 | private d.NearCallback nearCallback; |
71 | private d.NearCallback nearProbeCallback; | ||
68 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 72 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
69 | private List<ContactResult> m_contactResults = new List<ContactResult>(); | 73 | private List<ContactResult> m_contactResults = new List<ContactResult>(); |
70 | private RayFilterFlags CurrentRayFilter; | 74 | private RayFilterFlags CurrentRayFilter; |
@@ -74,169 +78,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
74 | { | 78 | { |
75 | m_scene = pScene; | 79 | m_scene = pScene; |
76 | nearCallback = near; | 80 | nearCallback = near; |
81 | nearProbeCallback = nearProbe; | ||
77 | ray = d.CreateRay(IntPtr.Zero, 1.0f); | 82 | ray = d.CreateRay(IntPtr.Zero, 1.0f); |
78 | d.GeomSetCategoryBits(ray,0); | 83 | d.GeomSetCategoryBits(ray, 0); |
84 | Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); | ||
85 | d.GeomSetCategoryBits(Box, 0); | ||
86 | Sphere = d.CreateSphere(IntPtr.Zero,1.0f); | ||
87 | d.GeomSetCategoryBits(Sphere, 0); | ||
88 | Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f); | ||
89 | d.GeomSetCategoryBits(Sphere, 0); | ||
79 | } | 90 | } |
80 | 91 | ||
81 | /// <summary> | 92 | public void QueueRequest(ODERayRequest req) |
82 | /// Queues request for a raycast to all world | ||
83 | /// </summary> | ||
84 | /// <param name="position">Origin of Ray</param> | ||
85 | /// <param name="direction">Ray direction</param> | ||
86 | /// <param name="length">Ray length</param> | ||
87 | /// <param name="retMethod">Return method to send the results</param> | ||
88 | public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod) | ||
89 | { | ||
90 | ODERayRequest req = new ODERayRequest(); | ||
91 | req.geom = IntPtr.Zero; | ||
92 | req.callbackMethod = retMethod; | ||
93 | req.Count = DefaultMaxCount; | ||
94 | req.length = length; | ||
95 | req.Normal = direction; | ||
96 | req.Origin = position; | ||
97 | req.filter = RayFilterFlags.AllPrims; | ||
98 | |||
99 | m_PendingRequests.Enqueue(req); | ||
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// Queues request for a raycast to particular part | ||
104 | /// </summary> | ||
105 | /// <param name="position">Origin of Ray</param> | ||
106 | /// <param name="direction">Ray direction</param> | ||
107 | /// <param name="length">Ray length</param> | ||
108 | /// <param name="retMethod">Return method to send the results</param> | ||
109 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod) | ||
110 | { | ||
111 | ODERayRequest req = new ODERayRequest(); | ||
112 | req.geom = geom; | ||
113 | req.callbackMethod = retMethod; | ||
114 | req.length = length; | ||
115 | req.Normal = direction; | ||
116 | req.Origin = position; | ||
117 | req.Count = DefaultMaxCount; | ||
118 | req.filter = RayFilterFlags.AllPrims; | ||
119 | |||
120 | m_PendingRequests.Enqueue(req); | ||
121 | } | ||
122 | |||
123 | public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) | ||
124 | { | ||
125 | ODERayRequest req = new ODERayRequest(); | ||
126 | req.geom = IntPtr.Zero; | ||
127 | req.callbackMethod = retMethod; | ||
128 | req.Count = DefaultMaxCount; | ||
129 | req.length = length; | ||
130 | req.Normal = direction; | ||
131 | req.Origin = position; | ||
132 | req.filter = RayFilterFlags.AllPrims | RayFilterFlags.land; | ||
133 | |||
134 | m_PendingRequests.Enqueue(req); | ||
135 | } | ||
136 | |||
137 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) | ||
138 | { | ||
139 | ODERayRequest req = new ODERayRequest(); | ||
140 | req.geom = geom; | ||
141 | req.callbackMethod = retMethod; | ||
142 | req.length = length; | ||
143 | req.Normal = direction; | ||
144 | req.Origin = position; | ||
145 | req.Count = DefaultMaxCount; | ||
146 | req.filter = RayFilterFlags.AllPrims; | ||
147 | |||
148 | m_PendingRequests.Enqueue(req); | ||
149 | } | ||
150 | |||
151 | /// <summary> | ||
152 | /// Queues a raycast | ||
153 | /// </summary> | ||
154 | /// <param name="position">Origin of Ray</param> | ||
155 | /// <param name="direction">Ray normal</param> | ||
156 | /// <param name="length">Ray length</param> | ||
157 | /// <param name="count"></param> | ||
158 | /// <param name="retMethod">Return method to send the results</param> | ||
159 | public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) | ||
160 | { | ||
161 | ODERayRequest req = new ODERayRequest(); | ||
162 | req.geom = IntPtr.Zero; | ||
163 | req.callbackMethod = retMethod; | ||
164 | req.length = length; | ||
165 | req.Normal = direction; | ||
166 | req.Origin = position; | ||
167 | req.Count = count; | ||
168 | req.filter = RayFilterFlags.AllPrims; | ||
169 | |||
170 | m_PendingRequests.Enqueue(req); | ||
171 | } | ||
172 | |||
173 | |||
174 | public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod) | ||
175 | { | ||
176 | ODERayRequest req = new ODERayRequest(); | ||
177 | req.geom = IntPtr.Zero; | ||
178 | req.callbackMethod = retMethod; | ||
179 | req.length = length; | ||
180 | req.Normal = direction; | ||
181 | req.Origin = position; | ||
182 | req.Count = count; | ||
183 | req.filter = filter; | ||
184 | |||
185 | m_PendingRequests.Enqueue(req); | ||
186 | } | ||
187 | |||
188 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) | ||
189 | { | ||
190 | ODERayRequest req = new ODERayRequest(); | ||
191 | req.geom = geom; | ||
192 | req.callbackMethod = retMethod; | ||
193 | req.length = length; | ||
194 | req.Normal = direction; | ||
195 | req.Origin = position; | ||
196 | req.Count = count; | ||
197 | req.filter = RayFilterFlags.AllPrims; | ||
198 | |||
199 | m_PendingRequests.Enqueue(req); | ||
200 | } | ||
201 | |||
202 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count,RayFilterFlags flags, RayCallback retMethod) | ||
203 | { | ||
204 | ODERayRequest req = new ODERayRequest(); | ||
205 | req.geom = geom; | ||
206 | req.callbackMethod = retMethod; | ||
207 | req.length = length; | ||
208 | req.Normal = direction; | ||
209 | req.Origin = position; | ||
210 | req.Count = count; | ||
211 | req.filter = flags; | ||
212 | |||
213 | m_PendingRequests.Enqueue(req); | ||
214 | } | ||
215 | |||
216 | public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod) | ||
217 | { | ||
218 | ODERayRequest req = new ODERayRequest(); | ||
219 | req.geom = IntPtr.Zero; | ||
220 | req.callbackMethod = retMethod; | ||
221 | req.length = length; | ||
222 | req.Normal = direction; | ||
223 | req.Origin = position; | ||
224 | req.Count = count; | ||
225 | req.filter = RayFilterFlags.AllPrims; | ||
226 | |||
227 | m_PendingRequests.Enqueue(req); | ||
228 | } | ||
229 | |||
230 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod) | ||
231 | { | 93 | { |
232 | ODERayRequest req = new ODERayRequest(); | 94 | if (req.Count == 0) |
233 | req.geom = geom; | 95 | req.Count = DefaultMaxCount; |
234 | req.callbackMethod = retMethod; | ||
235 | req.length = length; | ||
236 | req.Normal = direction; | ||
237 | req.Origin = position; | ||
238 | req.Count = count; | ||
239 | req.filter = RayFilterFlags.AllPrims; | ||
240 | 96 | ||
241 | m_PendingRequests.Enqueue(req); | 97 | m_PendingRequests.Enqueue(req); |
242 | } | 98 | } |
@@ -272,21 +128,64 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
272 | CurrentRayFilter = req.filter; | 128 | CurrentRayFilter = req.filter; |
273 | CurrentMaxCount = req.Count; | 129 | CurrentMaxCount = req.Count; |
274 | 130 | ||
131 | CollisionContactGeomsPerTest = req.Count & 0xffff; | ||
132 | |||
275 | closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1); | 133 | closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1); |
276 | backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1); | 134 | backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1); |
277 | 135 | ||
278 | d.GeomRaySetLength(ray, req.length); | 136 | if (req.callbackMethod is ProbeBoxCallback) |
279 | d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); | 137 | { |
280 | d.GeomRaySetParams(ray, 0, backfacecull); | 138 | if (CollisionContactGeomsPerTest > 80) |
281 | d.GeomRaySetClosestHit(ray, closestHit); | 139 | CollisionContactGeomsPerTest = 80; |
140 | d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z); | ||
141 | d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z); | ||
142 | d.Quaternion qtmp; | ||
143 | qtmp.X = req.orientation.X; | ||
144 | qtmp.Y = req.orientation.Y; | ||
145 | qtmp.Z = req.orientation.Z; | ||
146 | qtmp.W = req.orientation.W; | ||
147 | d.GeomSetOffsetWorldQuaternion(Box, ref qtmp); | ||
148 | } | ||
149 | else if (req.callbackMethod is ProbeSphereCallback) | ||
150 | { | ||
151 | if (CollisionContactGeomsPerTest > 80) | ||
152 | CollisionContactGeomsPerTest = 80; | ||
153 | |||
154 | d.GeomSphereSetRadius(Sphere, req.length); | ||
155 | d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z); | ||
156 | } | ||
157 | else if (req.callbackMethod is ProbePlaneCallback) | ||
158 | { | ||
159 | if (CollisionContactGeomsPerTest > 80) | ||
160 | CollisionContactGeomsPerTest = 80; | ||
161 | |||
162 | d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length); | ||
163 | } | ||
164 | |||
165 | else | ||
166 | { | ||
167 | if (CollisionContactGeomsPerTest > 25) | ||
168 | CollisionContactGeomsPerTest = 25; | ||
282 | 169 | ||
283 | if (req.callbackMethod is RaycastCallback) | 170 | d.GeomRaySetLength(ray, req.length); |
284 | // if we only want one get only one per colision pair saving memory | 171 | d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); |
285 | CurrentRayFilter |= RayFilterFlags.ClosestHit; | 172 | d.GeomRaySetParams(ray, 0, backfacecull); |
173 | d.GeomRaySetClosestHit(ray, closestHit); | ||
174 | |||
175 | if (req.callbackMethod is RaycastCallback) | ||
176 | // if we only want one get only one per Collision pair saving memory | ||
177 | CurrentRayFilter |= RayFilterFlags.ClosestHit; | ||
178 | } | ||
179 | |||
180 | if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0) | ||
181 | unchecked | ||
182 | { | ||
183 | CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; | ||
184 | } | ||
286 | 185 | ||
287 | if (req.geom == IntPtr.Zero) | 186 | if (req.geom == IntPtr.Zero) |
288 | { | 187 | { |
289 | // translate ray filter to colision flags | 188 | // translate ray filter to Collision flags |
290 | catflags = 0; | 189 | catflags = 0; |
291 | if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0) | 190 | if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0) |
292 | catflags |= CollisionCategories.VolumeDtc; | 191 | catflags |= CollisionCategories.VolumeDtc; |
@@ -303,15 +202,48 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
303 | 202 | ||
304 | if (catflags != 0) | 203 | if (catflags != 0) |
305 | { | 204 | { |
306 | d.GeomSetCollideBits(ray, (uint)catflags); | 205 | if (req.callbackMethod is ProbeBoxCallback) |
307 | doSpaceRay(req); | 206 | { |
207 | catflags |= CollisionCategories.Space; | ||
208 | d.GeomSetCollideBits(Box, (uint)catflags); | ||
209 | d.GeomSetCategoryBits(Box, (uint)catflags); | ||
210 | doProbe(req, Box); | ||
211 | } | ||
212 | else if (req.callbackMethod is ProbeSphereCallback) | ||
213 | { | ||
214 | catflags |= CollisionCategories.Space; | ||
215 | d.GeomSetCollideBits(Sphere, (uint)catflags); | ||
216 | d.GeomSetCategoryBits(Sphere, (uint)catflags); | ||
217 | doProbe(req, Sphere); | ||
218 | } | ||
219 | else if (req.callbackMethod is ProbePlaneCallback) | ||
220 | { | ||
221 | catflags |= CollisionCategories.Space; | ||
222 | d.GeomSetCollideBits(Plane, (uint)catflags); | ||
223 | d.GeomSetCategoryBits(Plane, (uint)catflags); | ||
224 | doPlane(req); | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | d.GeomSetCollideBits(ray, (uint)catflags); | ||
229 | doSpaceRay(req); | ||
230 | } | ||
308 | } | 231 | } |
309 | } | 232 | } |
310 | else | 233 | else |
311 | { | 234 | { |
312 | // if we select a geom don't use filters | 235 | // if we select a geom don't use filters |
313 | d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); | 236 | |
314 | doGeomRay(req); | 237 | if (req.callbackMethod is ProbePlaneCallback) |
238 | { | ||
239 | d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); | ||
240 | doPlane(req); | ||
241 | } | ||
242 | else | ||
243 | { | ||
244 | d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); | ||
245 | doGeomRay(req); | ||
246 | } | ||
315 | } | 247 | } |
316 | } | 248 | } |
317 | 249 | ||
@@ -396,6 +328,61 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
396 | } | 328 | } |
397 | } | 329 | } |
398 | 330 | ||
331 | private void doProbe(ODERayRequest req, IntPtr probe) | ||
332 | { | ||
333 | // Collide tests | ||
334 | if ((CurrentRayFilter & FilterActiveSpace) != 0) | ||
335 | { | ||
336 | d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); | ||
337 | d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback); | ||
338 | } | ||
339 | if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) | ||
340 | d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback); | ||
341 | if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) | ||
342 | d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback); | ||
343 | |||
344 | List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); | ||
345 | lock (m_PendingRequests) | ||
346 | { | ||
347 | cresult.AddRange(m_contactResults); | ||
348 | m_contactResults.Clear(); | ||
349 | } | ||
350 | if (req.callbackMethod is ProbeBoxCallback) | ||
351 | ((ProbeBoxCallback)req.callbackMethod)(cresult); | ||
352 | else if (req.callbackMethod is ProbeSphereCallback) | ||
353 | ((ProbeSphereCallback)req.callbackMethod)(cresult); | ||
354 | } | ||
355 | |||
356 | private void doPlane(ODERayRequest req) | ||
357 | { | ||
358 | // Collide tests | ||
359 | if (req.geom == IntPtr.Zero) | ||
360 | { | ||
361 | if ((CurrentRayFilter & FilterActiveSpace) != 0) | ||
362 | { | ||
363 | d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); | ||
364 | d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback); | ||
365 | } | ||
366 | if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) | ||
367 | d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback); | ||
368 | if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) | ||
369 | d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback); | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback); | ||
374 | } | ||
375 | |||
376 | List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); | ||
377 | lock (m_PendingRequests) | ||
378 | { | ||
379 | cresult.AddRange(m_contactResults); | ||
380 | m_contactResults.Clear(); | ||
381 | } | ||
382 | |||
383 | ((ProbePlaneCallback)req.callbackMethod)(cresult); | ||
384 | } | ||
385 | |||
399 | /// <summary> | 386 | /// <summary> |
400 | /// Method that actually initiates the raycast with a geom | 387 | /// Method that actually initiates the raycast with a geom |
401 | /// </summary> | 388 | /// </summary> |
@@ -450,7 +437,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
450 | private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) | 437 | private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) |
451 | { | 438 | { |
452 | IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; | 439 | IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; |
453 | if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest) | 440 | if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest) |
454 | return false; | 441 | return false; |
455 | 442 | ||
456 | IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); | 443 | IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); |
@@ -483,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
483 | int count = 0; | 470 | int count = 0; |
484 | try | 471 | try |
485 | { | 472 | { |
486 | count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); | 473 | count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); |
487 | } | 474 | } |
488 | catch (Exception e) | 475 | catch (Exception e) |
489 | { | 476 | { |
@@ -494,84 +481,210 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
494 | if (count == 0) | 481 | if (count == 0) |
495 | return; | 482 | return; |
496 | 483 | ||
484 | uint cat1 = d.GeomGetCategoryBits(g1); | ||
485 | uint cat2 = d.GeomGetCategoryBits(g2); | ||
486 | uint col1 = d.GeomGetCollideBits(g1); | ||
487 | uint col2 = d.GeomGetCollideBits(g2); | ||
488 | |||
489 | |||
497 | uint ID = 0; | 490 | uint ID = 0; |
498 | PhysicsActor p2 = null; | 491 | PhysicsActor p2 = null; |
499 | 492 | ||
500 | m_scene.actor_name_map.TryGetValue(g2, out p2); | 493 | m_scene.actor_name_map.TryGetValue(g2, out p2); |
501 | 494 | ||
502 | if (p2 == null) | 495 | if (p2 == null) |
503 | { | ||
504 | /* | ||
505 | string name; | ||
506 | |||
507 | if (!m_scene.geom_name_map.TryGetValue(g2, out name)) | ||
508 | return; | ||
509 | |||
510 | if (name == "Terrain") | ||
511 | { | ||
512 | // land colision | ||
513 | if ((CurrentRayFilter & RayFilterFlags.land) == 0) | ||
514 | return; | ||
515 | } | ||
516 | else if (name == "Water") | ||
517 | { | ||
518 | if ((CurrentRayFilter & RayFilterFlags.water) == 0) | ||
519 | return; | ||
520 | } | ||
521 | else | ||
522 | return; | ||
523 | */ | ||
524 | return; | 496 | return; |
525 | } | 497 | |
526 | else | 498 | switch (p2.PhysicsActorType) |
527 | { | 499 | { |
528 | switch (p2.PhysicsActorType) | 500 | case (int)ActorTypes.Prim: |
529 | { | ||
530 | case (int)ActorTypes.Prim: | ||
531 | 501 | ||
532 | RayFilterFlags thisFlags; | 502 | RayFilterFlags thisFlags; |
533 | 503 | ||
534 | if (p2.IsPhysical) | 504 | if (p2.IsPhysical) |
535 | thisFlags = RayFilterFlags.physical; | 505 | thisFlags = RayFilterFlags.physical; |
536 | else | 506 | else |
537 | thisFlags = RayFilterFlags.nonphysical; | 507 | thisFlags = RayFilterFlags.nonphysical; |
538 | 508 | ||
539 | if (p2.Phantom) | 509 | if (p2.Phantom) |
540 | thisFlags |= RayFilterFlags.phantom; | 510 | thisFlags |= RayFilterFlags.phantom; |
541 | 511 | ||
542 | if (p2.IsVolumeDtc) | 512 | if (p2.IsVolumeDtc) |
543 | thisFlags |= RayFilterFlags.volumedtc; | 513 | thisFlags |= RayFilterFlags.volumedtc; |
544 | 514 | ||
545 | if ((thisFlags & CurrentRayFilter) == 0) | 515 | if ((thisFlags & CurrentRayFilter) == 0) |
546 | return; | 516 | return; |
547 | 517 | ||
548 | ID = ((OdePrim)p2).LocalID; | 518 | ID = ((OdePrim)p2).LocalID; |
549 | break; | 519 | break; |
550 | 520 | ||
551 | case (int)ActorTypes.Agent: | 521 | case (int)ActorTypes.Agent: |
552 | 522 | ||
553 | if ((CurrentRayFilter & RayFilterFlags.agent) == 0) | 523 | if ((CurrentRayFilter & RayFilterFlags.agent) == 0) |
554 | return; | 524 | return; |
555 | else | 525 | else |
556 | ID = ((OdeCharacter)p2).LocalID; | 526 | ID = ((OdeCharacter)p2).LocalID; |
557 | break; | 527 | break; |
558 | 528 | ||
559 | case (int)ActorTypes.Ground: | 529 | case (int)ActorTypes.Ground: |
560 | 530 | ||
561 | if ((CurrentRayFilter & RayFilterFlags.land) == 0) | 531 | if ((CurrentRayFilter & RayFilterFlags.land) == 0) |
562 | return; | 532 | return; |
563 | break; | 533 | break; |
564 | 534 | ||
565 | case (int)ActorTypes.Water: | 535 | case (int)ActorTypes.Water: |
566 | 536 | ||
567 | if ((CurrentRayFilter & RayFilterFlags.water) == 0) | 537 | if ((CurrentRayFilter & RayFilterFlags.water) == 0) |
568 | return; | 538 | return; |
539 | break; | ||
540 | |||
541 | default: | ||
542 | break; | ||
543 | } | ||
544 | |||
545 | d.ContactGeom curcontact = new d.ContactGeom(); | ||
546 | |||
547 | // closestHit for now only works for meshs, so must do it for others | ||
548 | if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0) | ||
549 | { | ||
550 | // Loop all contacts, build results. | ||
551 | for (int i = 0; i < count; i++) | ||
552 | { | ||
553 | if (!GetCurContactGeom(i, ref curcontact)) | ||
569 | break; | 554 | break; |
570 | 555 | ||
571 | default: | 556 | ContactResult collisionresult = new ContactResult(); |
557 | collisionresult.ConsumerID = ID; | ||
558 | collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); | ||
559 | collisionresult.Depth = curcontact.depth; | ||
560 | collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, | ||
561 | curcontact.normal.Z); | ||
562 | lock (m_contactResults) | ||
563 | { | ||
564 | m_contactResults.Add(collisionresult); | ||
565 | if (m_contactResults.Count >= CurrentMaxCount) | ||
566 | return; | ||
567 | } | ||
568 | } | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | // keep only closest contact | ||
573 | ContactResult collisionresult = new ContactResult(); | ||
574 | collisionresult.ConsumerID = ID; | ||
575 | collisionresult.Depth = float.MaxValue; | ||
576 | |||
577 | for (int i = 0; i < count; i++) | ||
578 | { | ||
579 | if (!GetCurContactGeom(i, ref curcontact)) | ||
572 | break; | 580 | break; |
581 | |||
582 | if (curcontact.depth < collisionresult.Depth) | ||
583 | { | ||
584 | collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); | ||
585 | collisionresult.Depth = curcontact.depth; | ||
586 | collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, | ||
587 | curcontact.normal.Z); | ||
588 | } | ||
589 | } | ||
590 | |||
591 | if (collisionresult.Depth != float.MaxValue) | ||
592 | { | ||
593 | lock (m_contactResults) | ||
594 | m_contactResults.Add(collisionresult); | ||
573 | } | 595 | } |
574 | } | 596 | } |
597 | } | ||
598 | |||
599 | private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2) | ||
600 | { | ||
601 | if (g1 == IntPtr.Zero || g1 == g2) | ||
602 | return; | ||
603 | |||
604 | if (m_contactResults.Count >= CurrentMaxCount) | ||
605 | return; | ||
606 | |||
607 | if (d.GeomIsSpace(g1)) | ||
608 | { | ||
609 | try | ||
610 | { | ||
611 | d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback); | ||
612 | } | ||
613 | catch (Exception e) | ||
614 | { | ||
615 | m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message); | ||
616 | } | ||
617 | return; | ||
618 | } | ||
619 | |||
620 | int count = 0; | ||
621 | try | ||
622 | { | ||
623 | count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); | ||
624 | } | ||
625 | catch (Exception e) | ||
626 | { | ||
627 | m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); | ||
628 | return; | ||
629 | } | ||
630 | |||
631 | if (count == 0) | ||
632 | return; | ||
633 | |||
634 | uint ID = 0; | ||
635 | PhysicsActor p1 = null; | ||
636 | |||
637 | m_scene.actor_name_map.TryGetValue(g1, out p1); | ||
638 | |||
639 | if (p1 == null) | ||
640 | return; | ||
641 | |||
642 | switch (p1.PhysicsActorType) | ||
643 | { | ||
644 | case (int)ActorTypes.Prim: | ||
645 | |||
646 | RayFilterFlags thisFlags; | ||
647 | |||
648 | if (p1.IsPhysical) | ||
649 | thisFlags = RayFilterFlags.physical; | ||
650 | else | ||
651 | thisFlags = RayFilterFlags.nonphysical; | ||
652 | |||
653 | if (p1.Phantom) | ||
654 | thisFlags |= RayFilterFlags.phantom; | ||
655 | |||
656 | if (p1.IsVolumeDtc) | ||
657 | thisFlags |= RayFilterFlags.volumedtc; | ||
658 | |||
659 | if ((thisFlags & CurrentRayFilter) == 0) | ||
660 | return; | ||
661 | |||
662 | ID = ((OdePrim)p1).LocalID; | ||
663 | break; | ||
664 | |||
665 | case (int)ActorTypes.Agent: | ||
666 | |||
667 | if ((CurrentRayFilter & RayFilterFlags.agent) == 0) | ||
668 | return; | ||
669 | else | ||
670 | ID = ((OdeCharacter)p1).LocalID; | ||
671 | break; | ||
672 | |||
673 | case (int)ActorTypes.Ground: | ||
674 | |||
675 | if ((CurrentRayFilter & RayFilterFlags.land) == 0) | ||
676 | return; | ||
677 | break; | ||
678 | |||
679 | case (int)ActorTypes.Water: | ||
680 | |||
681 | if ((CurrentRayFilter & RayFilterFlags.water) == 0) | ||
682 | return; | ||
683 | break; | ||
684 | |||
685 | default: | ||
686 | break; | ||
687 | } | ||
575 | 688 | ||
576 | d.ContactGeom curcontact = new d.ContactGeom(); | 689 | d.ContactGeom curcontact = new d.ContactGeom(); |
577 | 690 | ||
@@ -638,6 +751,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
638 | d.GeomDestroy(ray); | 751 | d.GeomDestroy(ray); |
639 | ray = IntPtr.Zero; | 752 | ray = IntPtr.Zero; |
640 | } | 753 | } |
754 | if (Box != IntPtr.Zero) | ||
755 | { | ||
756 | d.GeomDestroy(Box); | ||
757 | Box = IntPtr.Zero; | ||
758 | } | ||
759 | if (Sphere != IntPtr.Zero) | ||
760 | { | ||
761 | d.GeomDestroy(Sphere); | ||
762 | Sphere = IntPtr.Zero; | ||
763 | } | ||
764 | if (Plane != IntPtr.Zero) | ||
765 | { | ||
766 | d.GeomDestroy(Plane); | ||
767 | Plane = IntPtr.Zero; | ||
768 | } | ||
641 | } | 769 | } |
642 | } | 770 | } |
643 | 771 | ||
@@ -650,5 +778,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
650 | public float length; | 778 | public float length; |
651 | public object callbackMethod; | 779 | public object callbackMethod; |
652 | public RayFilterFlags filter; | 780 | public RayFilterFlags filter; |
781 | public Quaternion orientation; | ||
653 | } | 782 | } |
654 | } \ No newline at end of file | 783 | } \ No newline at end of file |