diff options
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 207 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 16 |
2 files changed, 53 insertions, 170 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; |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 0d18adb..5113210 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -2580,7 +2580,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2580 | if (retMethod != null) | 2580 | if (retMethod != null) |
2581 | { | 2581 | { |
2582 | ODERayRequest req = new ODERayRequest(); | 2582 | ODERayRequest req = new ODERayRequest(); |
2583 | req.geom = IntPtr.Zero; | 2583 | req.actor = null; |
2584 | req.callbackMethod = retMethod; | 2584 | req.callbackMethod = retMethod; |
2585 | req.length = length; | 2585 | req.length = length; |
2586 | req.Normal = direction; | 2586 | req.Normal = direction; |
@@ -2597,7 +2597,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2597 | if (retMethod != null) | 2597 | if (retMethod != null) |
2598 | { | 2598 | { |
2599 | ODERayRequest req = new ODERayRequest(); | 2599 | ODERayRequest req = new ODERayRequest(); |
2600 | req.geom = IntPtr.Zero; | 2600 | req.actor = null; |
2601 | req.callbackMethod = retMethod; | 2601 | req.callbackMethod = retMethod; |
2602 | req.length = length; | 2602 | req.length = length; |
2603 | req.Normal = direction; | 2603 | req.Normal = direction; |
@@ -2625,7 +2625,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2625 | }; | 2625 | }; |
2626 | 2626 | ||
2627 | ODERayRequest req = new ODERayRequest(); | 2627 | ODERayRequest req = new ODERayRequest(); |
2628 | req.geom = IntPtr.Zero; | 2628 | req.actor = null; |
2629 | req.callbackMethod = retMethod; | 2629 | req.callbackMethod = retMethod; |
2630 | req.length = length; | 2630 | req.length = length; |
2631 | req.Normal = direction; | 2631 | req.Normal = direction; |
@@ -2663,7 +2663,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2663 | }; | 2663 | }; |
2664 | 2664 | ||
2665 | ODERayRequest req = new ODERayRequest(); | 2665 | ODERayRequest req = new ODERayRequest(); |
2666 | req.geom = IntPtr.Zero; | 2666 | req.actor = null; |
2667 | req.callbackMethod = retMethod; | 2667 | req.callbackMethod = retMethod; |
2668 | req.length = length; | 2668 | req.length = length; |
2669 | req.Normal = direction; | 2669 | req.Normal = direction; |
@@ -2710,7 +2710,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2710 | }; | 2710 | }; |
2711 | 2711 | ||
2712 | ODERayRequest req = new ODERayRequest(); | 2712 | ODERayRequest req = new ODERayRequest(); |
2713 | req.geom = geom; | 2713 | req.actor = actor; |
2714 | req.callbackMethod = retMethod; | 2714 | req.callbackMethod = retMethod; |
2715 | req.length = length; | 2715 | req.length = length; |
2716 | req.Normal = direction; | 2716 | req.Normal = direction; |
@@ -2745,7 +2745,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2745 | }; | 2745 | }; |
2746 | 2746 | ||
2747 | ODERayRequest req = new ODERayRequest(); | 2747 | ODERayRequest req = new ODERayRequest(); |
2748 | req.geom = IntPtr.Zero; | 2748 | req.actor = null; |
2749 | req.callbackMethod = retMethod; | 2749 | req.callbackMethod = retMethod; |
2750 | req.Normal = size; | 2750 | req.Normal = size; |
2751 | req.Origin = position; | 2751 | req.Origin = position; |
@@ -2777,7 +2777,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2777 | }; | 2777 | }; |
2778 | 2778 | ||
2779 | ODERayRequest req = new ODERayRequest(); | 2779 | ODERayRequest req = new ODERayRequest(); |
2780 | req.geom = IntPtr.Zero; | 2780 | req.actor = null; |
2781 | req.callbackMethod = retMethod; | 2781 | req.callbackMethod = retMethod; |
2782 | req.length = radius; | 2782 | req.length = radius; |
2783 | req.Origin = position; | 2783 | req.Origin = position; |
@@ -2819,7 +2819,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2819 | }; | 2819 | }; |
2820 | 2820 | ||
2821 | ODERayRequest req = new ODERayRequest(); | 2821 | ODERayRequest req = new ODERayRequest(); |
2822 | req.geom = geom; | 2822 | req.actor = null; |
2823 | req.callbackMethod = retMethod; | 2823 | req.callbackMethod = retMethod; |
2824 | req.length = plane.W; | 2824 | req.length = plane.W; |
2825 | req.Normal.X = plane.X; | 2825 | req.Normal.X = plane.X; |