aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs207
1 files changed, 45 insertions, 162 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 7fe3109..4f598ea 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -68,7 +68,6 @@ namespace OpenSim.Region.Physics.OdePlugin
68 /// ODE near callback delegate 68 /// ODE near callback delegate
69 /// </summary> 69 /// </summary>
70 private d.NearCallback nearCallback; 70 private d.NearCallback nearCallback;
71 private d.NearCallback nearProbeCallback;
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 71 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
73 private List<ContactResult> m_contactResults = new List<ContactResult>(); 72 private List<ContactResult> m_contactResults = new List<ContactResult>();
74 private RayFilterFlags CurrentRayFilter; 73 private RayFilterFlags CurrentRayFilter;
@@ -78,7 +77,6 @@ namespace OpenSim.Region.Physics.OdePlugin
78 { 77 {
79 m_scene = pScene; 78 m_scene = pScene;
80 nearCallback = near; 79 nearCallback = near;
81 nearProbeCallback = nearProbe;
82 ray = d.CreateRay(IntPtr.Zero, 1.0f); 80 ray = d.CreateRay(IntPtr.Zero, 1.0f);
83 d.GeomSetCategoryBits(ray, 0); 81 d.GeomSetCategoryBits(ray, 0);
84 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); 82 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
@@ -125,6 +123,24 @@ namespace OpenSim.Region.Physics.OdePlugin
125 { 123 {
126 if (req.callbackMethod != null) 124 if (req.callbackMethod != null)
127 { 125 {
126 IntPtr geom = IntPtr.Zero;
127 if (req.actor != null)
128 {
129 if (m_scene.haveActor(req.actor))
130 {
131 if (req.actor is OdePrim)
132 geom = ((OdePrim)req.actor).prim_geom;
133 else if (req.actor is OdeCharacter)
134 geom = ((OdePrim)req.actor).prim_geom;
135 }
136 if (geom == IntPtr.Zero)
137 {
138 NoContacts(req);
139 continue;
140 }
141 }
142
143
128 CurrentRayFilter = req.filter; 144 CurrentRayFilter = req.filter;
129 CurrentMaxCount = req.Count; 145 CurrentMaxCount = req.Count;
130 146
@@ -188,7 +204,7 @@ namespace OpenSim.Region.Physics.OdePlugin
188 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; 204 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
189 } 205 }
190 206
191 if (req.geom == IntPtr.Zero) 207 if (geom == IntPtr.Zero)
192 { 208 {
193 // translate ray filter to Collision flags 209 // translate ray filter to Collision flags
194 catflags = 0; 210 catflags = 0;
@@ -226,7 +242,7 @@ namespace OpenSim.Region.Physics.OdePlugin
226 catflags |= CollisionCategories.Space; 242 catflags |= CollisionCategories.Space;
227 d.GeomSetCollideBits(Plane, (uint)catflags); 243 d.GeomSetCollideBits(Plane, (uint)catflags);
228 d.GeomSetCategoryBits(Plane, (uint)catflags); 244 d.GeomSetCategoryBits(Plane, (uint)catflags);
229 doPlane(req); 245 doPlane(req,IntPtr.Zero);
230 } 246 }
231 else 247 else
232 { 248 {
@@ -242,12 +258,12 @@ namespace OpenSim.Region.Physics.OdePlugin
242 if (req.callbackMethod is ProbePlaneCallback) 258 if (req.callbackMethod is ProbePlaneCallback)
243 { 259 {
244 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); 260 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
245 doPlane(req); 261 doPlane(req,geom);
246 } 262 }
247 else 263 else
248 { 264 {
249 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); 265 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
250 doGeomRay(req); 266 doGeomRay(req,geom);
251 } 267 }
252 } 268 }
253 } 269 }
@@ -267,6 +283,23 @@ namespace OpenSim.Region.Physics.OdePlugin
267 /// <param name="req"></param> 283 /// <param name="req"></param>
268 /// 284 ///
269 285
286 private void NoContacts(ODERayRequest req)
287 {
288 if (req.callbackMethod is RaycastCallback)
289 {
290 ((RaycastCallback)req.callbackMethod)(false, Vector3.Zero, 0, 0, Vector3.Zero);
291 return;
292 }
293 List<ContactResult> cresult = new List<ContactResult>();
294
295 if (req.callbackMethod is RayCallback)
296 ((RayCallback)req.callbackMethod)(cresult);
297 else if (req.callbackMethod is ProbeBoxCallback)
298 ((ProbeBoxCallback)req.callbackMethod)(cresult);
299 else if (req.callbackMethod is ProbeSphereCallback)
300 ((ProbeSphereCallback)req.callbackMethod)(cresult);
301 }
302
270 private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton; 303 private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
271// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; 304// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
272 private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; 305 private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
@@ -358,10 +391,10 @@ namespace OpenSim.Region.Physics.OdePlugin
358 ((ProbeSphereCallback)req.callbackMethod)(cresult); 391 ((ProbeSphereCallback)req.callbackMethod)(cresult);
359 } 392 }
360 393
361 private void doPlane(ODERayRequest req) 394 private void doPlane(ODERayRequest req,IntPtr geom)
362 { 395 {
363 // Collide tests 396 // Collide tests
364 if (req.geom == IntPtr.Zero) 397 if (geom == IntPtr.Zero)
365 { 398 {
366 if ((CurrentRayFilter & FilterActiveSpace) != 0) 399 if ((CurrentRayFilter & FilterActiveSpace) != 0)
367 { 400 {
@@ -375,7 +408,7 @@ namespace OpenSim.Region.Physics.OdePlugin
375 } 408 }
376 else 409 else
377 { 410 {
378 d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback); 411 d.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback);
379 } 412 }
380 413
381 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); 414 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
@@ -392,10 +425,10 @@ namespace OpenSim.Region.Physics.OdePlugin
392 /// Method that actually initiates the raycast with a geom 425 /// Method that actually initiates the raycast with a geom
393 /// </summary> 426 /// </summary>
394 /// <param name="req"></param> 427 /// <param name="req"></param>
395 private void doGeomRay(ODERayRequest req) 428 private void doGeomRay(ODERayRequest req, IntPtr geom)
396 { 429 {
397 // Collide test 430 // Collide test
398 d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test 431 d.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
399 432
400 if (req.callbackMethod is RaycastCallback) 433 if (req.callbackMethod is RaycastCallback)
401 { 434 {
@@ -607,156 +640,6 @@ namespace OpenSim.Region.Physics.OdePlugin
607 } 640 }
608 } 641 }
609 642
610 private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
611 {
612 if (g1 == IntPtr.Zero || g1 == g2)
613 return;
614
615 if (m_contactResults.Count >= CurrentMaxCount)
616 return;
617
618 if (d.GeomIsSpace(g1))
619 {
620 try
621 {
622 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
623 }
624 catch (Exception e)
625 {
626 m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
627 }
628 return;
629 }
630
631 int count = 0;
632 try
633 {
634 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
635 }
636 catch (Exception e)
637 {
638 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
639 return;
640 }
641
642 if (count == 0)
643 return;
644
645 uint ID = 0;
646 PhysicsActor p1 = null;
647
648 m_scene.actor_name_map.TryGetValue(g1, out p1);
649
650 if (p1 == null)
651 return;
652
653 switch (p1.PhysicsActorType)
654 {
655 case (int)ActorTypes.Prim:
656
657 RayFilterFlags thisFlags;
658
659 if (p1.IsPhysical)
660 thisFlags = RayFilterFlags.physical;
661 else
662 thisFlags = RayFilterFlags.nonphysical;
663
664 if (p1.Phantom)
665 thisFlags |= RayFilterFlags.phantom;
666
667 if (p1.IsVolumeDtc)
668 thisFlags |= RayFilterFlags.volumedtc;
669
670 if ((thisFlags & CurrentRayFilter) == 0)
671 return;
672
673 ID = ((OdePrim)p1).LocalID;
674 break;
675
676 case (int)ActorTypes.Agent:
677
678 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
679 return;
680 else
681 ID = ((OdeCharacter)p1).LocalID;
682 break;
683
684 case (int)ActorTypes.Ground:
685
686 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
687 return;
688 break;
689
690 case (int)ActorTypes.Water:
691
692 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
693 return;
694 break;
695
696 default:
697 break;
698 }
699
700 d.ContactGeom curcontact = new d.ContactGeom();
701
702 // closestHit for now only works for meshs, so must do it for others
703 if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
704 {
705 // Loop all contacts, build results.
706 for (int i = 0; i < count; i++)
707 {
708 if (!GetCurContactGeom(i, ref curcontact))
709 break;
710
711 ContactResult collisionresult = new ContactResult();
712 collisionresult.ConsumerID = ID;
713 collisionresult.Pos.X = curcontact.pos.X;
714 collisionresult.Pos.Y = curcontact.pos.Y;
715 collisionresult.Pos.Z = curcontact.pos.Z;
716 collisionresult.Depth = curcontact.depth;
717 collisionresult.Normal.X = curcontact.normal.X;
718 collisionresult.Normal.Y = curcontact.normal.Y;
719 collisionresult.Normal.Z = curcontact.normal.Z;
720 lock (m_contactResults)
721 {
722 m_contactResults.Add(collisionresult);
723 if (m_contactResults.Count >= CurrentMaxCount)
724 return;
725 }
726 }
727 }
728 else
729 {
730 // keep only closest contact
731 ContactResult collisionresult = new ContactResult();
732 collisionresult.ConsumerID = ID;
733 collisionresult.Depth = float.MaxValue;
734
735 for (int i = 0; i < count; i++)
736 {
737 if (!GetCurContactGeom(i, ref curcontact))
738 break;
739
740 if (curcontact.depth < collisionresult.Depth)
741 {
742 collisionresult.Pos.X = curcontact.pos.X;
743 collisionresult.Pos.Y = curcontact.pos.Y;
744 collisionresult.Pos.Z = curcontact.pos.Z;
745 collisionresult.Depth = curcontact.depth;
746 collisionresult.Normal.X = curcontact.normal.X;
747 collisionresult.Normal.Y = curcontact.normal.Y;
748 collisionresult.Normal.Z = curcontact.normal.Z;
749 }
750 }
751
752 if (collisionresult.Depth != float.MaxValue)
753 {
754 lock (m_contactResults)
755 m_contactResults.Add(collisionresult);
756 }
757 }
758 }
759
760 /// <summary> 643 /// <summary>
761 /// Dereference the creator scene so that it can be garbage collected if needed. 644 /// Dereference the creator scene so that it can be garbage collected if needed.
762 /// </summary> 645 /// </summary>
@@ -788,7 +671,7 @@ namespace OpenSim.Region.Physics.OdePlugin
788 671
789 public struct ODERayRequest 672 public struct ODERayRequest
790 { 673 {
791 public IntPtr geom; 674 public PhysicsActor actor;
792 public Vector3 Origin; 675 public Vector3 Origin;
793 public Vector3 Normal; 676 public Vector3 Normal;
794 public int Count; 677 public int Count;