detecting separation

Jun 24, 2014 at 3:34 PM
Hi,

I need to detect separation between two object that have just collided. I use OnSeparationEventHandler but it is never called. What I do wrong?
body.OnSeparation += new OnSeparationEventHandler(LaserSeparation);

...

        public void LaserSeparation(Fixture f1, Fixture f2)
        {
            if (closestBody == f2.Body)
            {
                closestBody = null;
            }
        }
Jun 25, 2014 at 11:11 AM
Hi,

your code seems fine, what version of FPE are you using ?

Also try :
body.OnSeparation += LaserSeparation;
instead of
body.OnSeparation += new OnSeparationEventHandler(LaserSeparation);
Jun 25, 2014 at 1:26 PM
I use FPE 3.5. Your clue doesn't solve the problem. So maybe i'll clarify the case.

I have object without collision. My OnCollisionEventHandler methood always return false for it. I need to calculate the nearest object on it from a certain point.
        public bool LaserCollision(Fixture f1, Fixture f2, Contact contact)
        {
            
            if (closestBody == null && f2.UserData is Meteorite)
            {
                closestBody = f2.Body;
            }
            else
            {
                if ((startPosition - ConvertUnits.ToDisplayUnits(f2.Body.Position)).Length() < currentRadius && f2.UserData is Meteorite)
                {
                    closestBody = f2.Body;
                }
            }

            return false;
        }

        public void LaserSeparation(Fixture f1, Fixture f2)
        {
            if (closestBody == f2.Body)
            {
                closestBody = null;
            }
        }

       public void Update()
       {
            if (closestBody == null)
            {
                currentRadius = radius;
            }
            else
            {
                currentRadius = (startPosition - ConvertUnits.ToDisplayUnits(closestBody.Position)).Length();
            }
        }
It's working good, but i need to reset closestBody when object is separating from that body, but OnSeparationEventHandler is never called. Or maybe if onCollision returns false, it never calls onSeparate? So how to do this?
Jun 27, 2014 at 2:41 PM
Edited Jun 27, 2014 at 2:41 PM
Or maybe if onCollision returns false, it never calls onSeparate?
I was wondering also...

You should use RayCasting to get your nearest object.
Jun 28, 2014 at 10:22 AM
Edited Jun 28, 2014 at 10:24 AM
I was wondering also...
Yes, it's true. I've checked it.

Soo, I've solved the problem. I've set IsSensor field to true and used ContactList to get colliding objects.

However, this solution, seems to me not very elegant and computationally expensive. I wonder if I would use ray cast, but I've never used it and i can't find any Farseer example of it. Can you show an example of the using rays?
Jun 29, 2014 at 12:43 PM
You can use RayCast like that :
physicWorld.RayCast((fixture, hitPosition, normal, fraction) =>
{
    //raycast logic
},
startPosition, endPosition);
This is pretty simple to use : each time your raycast will hit an object, the part with the "//raycast logic" will be called with the 4th first parameters as returned values (fixture collided, position of the impact, normal and fraction).
All you need to set is the startPosition and endPosition !
Jun 30, 2014 at 11:25 AM
Thanks a lot for this anwser, ray casts is much easier than my algorithm. But i have problem with it. When on rays way are more objects it going crazy and it don't know which one is the closest. It works nice when on its way is only one object.
      public void Update(ref World world)
      {
            currentRadius = radius;
            world.RayCast((fixture, hitPosition, normal, fraction) =>
            {
                currentRadius = (startPosition - ConvertUnits.ToDisplayUnits(hitPosition)).Length();
                return 1.0f;
            },
            ConvertUnits.ToSimUnits(startPosition), ConvertUnits.ToSimUnits(startPosition + (direction * radius)));
       }
I've prepared a poor quality gifs to show both cases:
One object on way:
http://s29.postimg.org/eu1rs7dyt/Cyber_Kid_2014_06_30_11_57_14_35.gif
Two or more objects:
http://s22.postimg.org/mo66tften/Cyber_Kid_2014_06_30_11_58_01_34.gif

Am I doing something wrong? What is the meaning of the float value returned by a function?
Jun 30, 2014 at 11:40 AM
You need to handle your raycast func return depending on what you want (forgot to mention that in my previous post sorry) :

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
Jun 30, 2014 at 11:52 AM
Thank you, it's just that what I was looking!