This project has moved and is read-only. For the latest updates, please go here.

Oddities with sensor collision detection

Topics: Developer Forum
Mar 10, 2015 at 8:33 AM
Edited Mar 10, 2015 at 4:10 PM

I've been looking around, but I am unable to come up with anything via search that may correspond with my problem.

I have a situation where I have two rectangular fixtures that correspond to the same body.
Each fixture is the same size and overlap each other. One fixture is a sensor and it is slightly offset above the other one (by 0.5). Think of this like a floor (50 width, 1 height) where the sensor fixture is slightly raised and is able to detect an object coming in for a landing.

The problem I am having is that when a third object is falling, the sensor's OnCollided event is triggered AFTER the regular non-sensor fixture, even though the sensor is above (and thus should hit before) the non-sensor one. If I change the sensor to a regular non-sensor fixture, the collisions work as expected. It almost feels like the sensor isn't necessarily getting checked with each step.

I have tested with all bodies being bullets and vice versa and I can't seem to figure this out. Is anyone able to provide some input on this?

If necessary, I can try to toss up an example. (Farseer 3.5)
Mar 12, 2015 at 7:15 AM
Edited Mar 12, 2015 at 7:19 AM
After a significant amount of testing, I was able to figure this out. It was kind of a 'duh' moment for me, but at least I can move on.

Details for those interested:
I was calling my physics ticks (world.StepSimulation) at the beginning of each game loop. The loop would continue to execute my game logic, and then eventually reset the loop for subsequent steps.

My problem was that I have my game loop sequenced to operate at a specific tickrate (in my case, 60 ticks per second). That means that there was a 16ms gap (minimum) between each world step. My logic for stepping the world was to simply take the delta (let's say 16 milliseconds) and pass that through to a single step. ie: world.StepSimulation(0.0166F).

I changed the logic to do multiple steps (10) per tick via a for loop like this:
for(int i = 0; i  < numSteps; i++)
    world.StepSimulation(timeDelta / numSteps);
This seemed to solve the problem for me.

This isn't necessarily ideal, but it works. The best solution, without taking a look at the guts of Farseer, is to change how the Farseer logic handles the order of executing collision events when there are multiple collisions on the same object. If I were to guess, it just takes whatever comes first in the body list, and if they collide, execute its callback without regard to whether another object should have collided first.
Marked as answer by PointSix on 3/11/2015 at 11:15 PM