SENSORS

25
Jun
2012

If we use maskBits and categoryBits to avoid collision between two fixtures, they don't generate any BeginContact/EndContact information. It means that there is no way to find out when the fixtures overlap using maskBits and categoryBits.

So if we want to know when two fixtures overlap yet there should be no collision response, this will be done using Sensors. A sensor is a fixture that detects collision but does not produce a response.

"A fixture can be made into a 'sensor' by setting the isSensor member of the fixture definition to true when you create it, or by calling SetSensor(bool) on the fixture after it has been created if you need to change it during the simulation. Sensors behave as if their maskBits is set to zero - they never collide with anything. But they do generate BeginContact/EndContact callbacks to let us know when they start or stop overlapping another fixture.

All other features of sensor fixtures remain the same as for a normal fixture. They can be added to any type of body. They still have a mass and will affect the overall mass of the body they are attached to. Remember you can have more than one fixture on a body so you can have a mix of solid shapes and sensors, allowing for all kinds of neat things. You can flag any fixture as being a sensor. Sensors may be static or dynamic."

--- from iforce2d.net


For setting a fixture as sensor -->

var fixDef = new b2FixtureDef;
fixDef.isSensor = true;
Here is the code snippet which gives an Output when there is BEGINNING of contact. We can also have output when contact ENDS.
var listener = new Box2D.Dynamics.b2ContactListener;
listener.BeginContact = function(contact) { // will be fired when contact begins
    fxA=contact.GetFixtureA(); // 1st FIXTURE which COLLIDES
    fxB=contact.GetFixtureB(); // 2nd FIXTURE which COLLIDES
    sA=fxA.IsSensor(); // Will store whether 1st fixture is a sensor or not (true or false)
    sB=fxB.IsSensor(); // Will store whether 2nd fixture is a sensor or not (true or false)
    if((sA && !sB) || (sB && !sA))	{ // Will go on further iff Fixture A or B not both are sensors.
        if(sA)	{ // If Fixture A is a Sensor
        	$('#cc').prepend(contact.GetFixtureB().GetBody().GetUserData() + ' is in the viscinity of body '+contact.GetFixtureA().GetBody().GetUserData()+'
'); // Output } else { // If Fixture B is a Sensor $('#cc').prepend(contact.GetFixtureA().GetBody().GetUserData() + ' is in the viscinity of body '+contact.GetFixtureB().GetBody().GetUserData()+'
'); // Output } } }

By administrator at 01:08:00 AM 3 Comment(s)

Comments

I think ther is no need to add the listener inside the update function. I put it outside the update function and it works. What is the difference? I would say that putting it inside the update function will add a lot of listeners to the world, but that's not the case because the world is not dispatching multiple events, so, I really don't know.

By alvaro obyrne on 29 Apr, 2013 at 02:05:06 PM

I am a bit confused…
How do you know which body has fxA and which fxB?
Do you have to iterate over the bodies in the world in the if…else
statement so that, via the user data, to assign actions to the bodies
once the collision have happened???

By haris on 19 Jan, 2015 at 09:02:21 AM

You DON'T! In the above example we don't have a lot of bodies. If you want to do some "action" with only certain sensor bodies use "USERDATA".

By administrator on 19 Jan, 2015 at 06:24:38 PM

Add a Comment

Please enter the email address.Invalid format. (Won't be Displayed)
Notify me of followup comments
Enter the displayed Code: captcha