Search code examples
vb.netxnaphysicsfarseer

Raycast missing detections using Farseer Physics in VB.NET.XNA


I'm using a raycast to determine the anchor location of a ropejoint. By using some simple draw calls, I can see that the ropejoint is being reliably created at the point the raycast returns. My problem lies in the return point. It occasionally passes through a body, returning a point on the opposite border, and sometimes inside the body. It seems to consistently fail when it does, that is to say, if I cast a ray that passes through repeatedly, it continues to pass through and return the same incorrect point. This leads me to believe there is a problem with my bodies. I am using the TextureToBody convertor for the bodies in question.

Another, lesser, issue is that i have to subtract 10/64 in each direction from my joints position to have it accurately attach. I have no idea why this is happening. (64pixels=1meter is the conversion ratio I'm using)

Raycast method:

    Private Sub castRay(startPoint As Vector2, direction As Vector2)
        direction *= 25
        direction.Y = (-direction.Y)
        world.RayCast(Function(fixture As Fixture, point As Vector2, normal As Vector2, fraction As Single)
                          Dim body As Body = fixture.Body

                          ropeContactFixture = fixture
                          ropeContactPoint = point
                          ropeJoint = New RopeJoint(Me.body, fixture.Body, New Vector2(0, 0), point - ropeContactFixture.Body.Position - (New Vector2(10, 10) / 64))
                          Return 0
                      End Function, startPoint, startPoint + direction)
    End Sub

Solution

  • Based on my use of Farseer you should make a list of all points returned by RayCast and then sort them by distance.

    Taken from Farseers code -

         Ray-cast the world for all fixtures in the path of the ray. Your callback
         controls whether you get the closest point, any point, or n-points.
         The ray-cast ignores shapes that contain the starting point.
    
         Inside the callback:
         return -1: ignore this fixture and continue
         return 0: terminate the ray cast
         return fraction: clip the ray to this point
         return 1: don't clip the ray and continue
    

    So using this knowledge you should be able to make a list of points along the ray, find the closest, and then make the rope.

    As a side note I'm not sure why you are inverting direction.Y, but you should make sure this is what you intended to do.