Collision filtering using masking not working properly

Post Reply
User avatar
godlike
Posts: 19
Joined: Fri Feb 19, 2010 7:09 pm
Contact:

Collision filtering using masking not working properly

Post by godlike » Mon Jul 26, 2010 1:13 pm

I've tried to test the collision filtering feature using masking as seen here http://bulletphysics.org/mediawiki-1.5. ... sing_masks

I chose to make a test using the BasicDemo (one static big box-shaped body for ground and many small box-shaped bodies falling from a height). I've altered the code in BasicDemo::initPhysics() so that the small boxes will interact with the ground but not with themselves.

For the ground body:

Code: Select all

static_cast<btDiscreteDynamicsWorld*>(m_dynamicsWorld)->addRigidBody(body, COL_WALL, COL_NOTHING);
For the small bodies:

Code: Select all

static_cast<btDiscreteDynamicsWorld*>(m_dynamicsWorld)->addRigidBody(body, COL_SHIP, COL_WALL);
The problem is that the small boxes pass right through the ground. If I alter the code for the ground creation with this:

Code: Select all

static_cast<btDiscreteDynamicsWorld*>(m_dynamicsWorld)->addRigidBody(body, COL_WALL, COL_SHIP);
it working as it should.


It appears that there is a conflict with the wiki tutorial and something is not right. Any ideas?

Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Collision filtering using masking not working properly

Post by Flix » Tue Jul 27, 2010 10:57 am

I don't have a clean answer for you (since I haven't tried the collision flags in the wiki), but I suggest you create some more flags (i.e. COL_GROUND, COL_EVERYTHING (that contains all the others except COL_NOTHING)).

Then you can make the ground collide this everything with:

Code: Select all

btWorld->addRigidBody(ground, COL_GROUND, COL_EVERYTHING);
and the small bodies not collide with themselves with:

Code: Select all

btWorld->addRigidBody(ground, COL_SMALLBODIES, COL_EVERYTHING^COL_SMALLBODIES);
or something like that.

As you can see, if you just want some objects in a group not to collide with each other, you can simply use the last line, and add the ground object as usual (without any collision group/flag).

Hope this helps.

[Edit] Of course if you use:

Code: Select all

btWorld->addRigidBody(ground, COL_GROUND, COL_NOTHING);
you want the ground object (that you put in the COL_GROUND group) to collide with nothing (as you correctly experience).

Alkane
Posts: 7
Joined: Sat Jul 10, 2010 8:34 pm

Re: Collision filtering using masking not working properly

Post by Alkane » Wed Jul 28, 2010 2:08 pm

I had the same issues as you and went to the same conclusion, I assumed the wiki notes might be based on an older version of bullet and this behavior has changed.
For sure, in the recent versions there's no such thing as "one way collision" like the wiki seems to imply, since bullet checks the flag of both objects and does not do the collision in case one of the object doesn't have the other object's flag.

Prompt
Posts: 13
Joined: Wed Jul 28, 2010 9:31 pm
Contact:

Re: Collision filtering using masking not working properly

Post by Prompt » Wed Jul 28, 2010 9:38 pm

Yes, wiki content don't work properly!

Try with that:

Code: Select all

    // Collision groups & masks
    #define BIT(x) (1<<(x))
    enum collisiontypes 
    {
        COL_NOTHING  = 0,        //< Collide with nothing
        COL_WALL     = BIT(1),   //< Collide with walls
        COL_SPHERE   = BIT(2),   //< Collide with spheres
        COL_TRIANGLE = BIT(3),   //< Collide with triangles
        COL_QUAD     = BIT(4)    //< Collide with quads
    };

    int wallCollidesWith     = COL_WALL | COL_SPHERE | COL_TRIANGLE | COL_QUAD;
    int sphereCollidesWith   = COL_WALL | COL_SPHERE | COL_TRIANGLE;
    int triangleCollidesWith = COL_WALL | COL_TRIANGLE | COL_QUAD;
    int quadCollidesWith     = COL_WALL | COL_QUAD | COL_SPHERE;
Y use in my test WALL mask for ground body and 3 types of shapes. In all mask groups, all collides with WALL objects for to see the test correctly.

Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Collision filtering using masking not working properly

Post by Flix » Thu Jul 29, 2010 9:27 am

Well, it seems that many people make the same mistake (reported here too):
http://bulletphysics.org/Bullet/phpBB3/ ... sion+flags

So it's better to point out that:
1) if you use a collision mask equal to zero, the object won't collide with anything.
2) As Alkane said, the collision happens only if both the two collision mask equations are satisfied.
3) Additionally I would add that the new collision filter groups should be compatible with the ones that Bullet uses by default:

Code: Select all

///optional filtering to cull potential collisions
	enum CollisionFilterGroups
	{
	        DefaultFilter = 1,
	        StaticFilter = 2,
	        KinematicFilter = 4,
	        DebrisFilter = 8,
			SensorTrigger = 16,
			CharacterFilter = 32,
	        AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
	};
This means that for example when you add an object to the world without arguments (and probably when raycasting without arguments), Bullet uses the group DefaultFilter and the mask AllFilter that has all bit sets; if you use a NoCollision group you should create a new AllFilter mask that does not include it and ALWAYS add objects to the world / perform raycasts with the new collision group/flags. Also I would start making new flags past "32".
4) Another thing that should be useful to know is that the collision group/mask is passed as a "short int".

A lot of time ago I posted this message:
http://bulletphysics.org/Bullet/phpBB3/ ... lags#p7525
in which I created new flags (at that time I started at "32" because the CharacterFilter was not present), and subclassed the Bullet world so that I could use the addRigidBody method without arguments and still use a NoCollision flag (in my experience a NoCollision flag is not very useful, but for example, if I have a ghost oject frustum or some kind of sensor object, maybe I might like the AllFilter flag not to include it by default: I suggest using this approach only if the NO_CONTACT_RESPONSE method is not good for you...).

Hope this is useful to cut down the number of future posts about problems with collision flags :)

Post Reply