Maarten Baert's website

Game Maker / C++ projects

Home Model Creator ExtremePhysics Game Maker DLLs SimpleScreenRecorder AlterPCB Quadcopters   Recent comments Search

Last modified: Mon, 8 Apr 2013
Refresh

Collision filtering

Actually this has been explained already in Getting started, but collision filtering is relatively complex and apparenty not everyone understands the short explanation. This tutorial gives a more detailed explanation on how ep_shape_set_collision works.

Quote: Getting started

The collision system ExtremePhysics uses takes three values: collision mask 1, collision mask 2 and group. Collision mask 1 and collision mask 2 are 32-bit unsigned integers. Collision mask 1 stores the group the shape belongs to, collision mask 2 stores the groups the shape should collide with. If collision mask 1 matches collision mask 2 or collision mask 2 matches collision mask 1, the bodies will collide. But if they are in the same group (not group 0), they will never collide.

// pseudo-code
if (body1.mask1 & body2.mask2 != 0 or body1.mask2 & body2.mask1 != 0) and (body1.group == 0 or body1.group != body2.group) {
    // collision
} else {
    // no collision
}

Groups are useful if your game uses lots of small groups of bodies that can't collide, like cars (the wheels shouldn't collide with the car, otherwise they can't overlap).

In the following examples, X = (1,2,3) means:

  • The first collision mask of a body of type X is 1 (binary 00000000 00000000 00000000 00000001)

  • The second collision mask of a body of type X is 2 (binary 00000000 00000000 00000000 00000010)

  • The group of a body of type X is 3.

Most of the time you don't need groups. You can indicate you don't want to use groups by setting group to 0.

A = (1,1|2|4,0)
B = (2,1|2,0)
C = (4,1,0)

This means:

  • A collides with A, B and C

  • B collides with A and B

  • C collides with A

Icuurd12b42 wrote an excellent explanation of this example:

Quote: Icuurd12b42

A = (1,1|2|4,0)
B = (2,1|2,0)
C = (4,1,0)

A says. I am
binary 0001 (1) and I collide with
binary 0001 (1) (self) and
binary 0010 (2) (B) and
binary 0100 (4) (C)
=
binary 0111 (A,B and C combined)

B says. I am
binary 0010 (2) and I collide with
binary 0001 (1) (A) and
binary 0010 (2) (self)
=
binary 0011 (A,B and C combined; 1|2)

C says. I am
binary 0100 (4) and I collide with
binary 0001 (1) (A)
=
binary 0001 (only A)

You can use groups to filter collisions between small groups of bodies:

A1 = (1,1,1)
A2 = (1,1,2)
A3 = (1,1,3)
...

This means:

  • A1 collides with A2, A3, ... (but not with other bodies of type A1)

  • A2 collides with A1, A3, ... (but not with other bodies of type A2)

  • A3 collides with A2, A3, ... (but not with other bodies of type A3)

  • ...

This is very useful if your game uses lots of small groups of bodies that can't collide, because the number of groups is unlimited (1 to 2^32-1, actually). So if you have a car and you don't want the wheels to collide with the body of the (same) car, groups are a good choice to achieve this. Just put the wheels in the same group as the car.

You can also combine collision masks and groups:

A1 = (1,1|2|4,1)
A2 = (1,1|2|4,2)
A3 = (1,1|2|4,3)
B = (2,1|2,0)
C = (4,1,0)

This means:

  • A1 collides with A2, A3, B and C

  • A2 collides with A1, A3, B and C

  • A3 collides with A1, A2, B and C

  • B collides with A1, A2, A3 and B

  • C collides with A1, A2 and A3


Comments

Olifudge

Comment #1: Fri, 3 Dec 2010, 17:16 (GMT+1, DST)

Quote


Just a question, why (and how) in your examples does it say "collide1a" and "collide1b" in the shape collision code? Thanks in advance

Maarten Baert

Administrator

Comment #2: Fri, 10 Dec 2010, 20:28 (GMT+1, DST)

Quote


Quote: Olifudge

Just a question, why (and how) in your examples does it say "collide1a" and "collide1b" in the shape collision code? Thanks in advance

Those are just constants, both are set to 1 I think.

Rpgillespie

Comment #3: Tue, 10 Jan 2012, 5:55 (GMT+1, DST)

Quote


So there are 32 possible collision masks, and each one has to be a power of 2, correct?

Last modified: Tue, 10 Jan 2012, 6:33 (GMT+1, DST)

Maarten Baert

Administrator

Comment #4: Thu, 19 Jan 2012, 23:34 (GMT+1, DST)

Quote


Quote: Rpgillespie

So there are 32 possible collision masks, and each one has to be a power of 2, correct?

Yes. But you can also use combinations of course, that's the point.

Earacher

Comment #5: Sat, 18 May 2013, 11:40 (GMT+1, DST)

Quote


Hello Maarten.
Can I use group like this: 1|2|4|8 ??

Maarten Baert

Administrator

Comment #6: Sat, 18 May 2013, 16:34 (GMT+1, DST)

Quote


Quote: Earacher

Hello Maarten.
Can I use group like this: 1|2|4|8 ??

No. A shape can only belong to one group. Try to use collision masks instead.

Last modified: Sat, 18 May 2013, 16:35 (GMT+1, DST)

7upnamk

Comment #7: Wed, 30 May 2018, 6:09 (GMT+1, DST)

Quote


Hi maarten. I never work with bitwise operation before so that i've been confused so much with your destructible terrain example. In the terrainblock_init script, i cant understand this:

mask = (1<<(size+1))|1;

why do you add

|1

into this? I've tried to comment like this

mask = (1<<(size+1))//|1;

and it still worked.
Sorry about my bad english
Thanks so much for your effecient extension!

Maarten Baert

Administrator

Comment #8: Fri, 1 Jun 2018, 1:41 (GMT+1, DST)

Quote


Quote: 7upnamk

Hi maarten. I never work with bitwise operation before so that i've been confused so much with your destructible terrain example. In the terrainblock_init script, i cant understand this:

mask = (1<<(size+1))|1;

why do you add

|1

into this? I've tried to comment like this

mask = (1<<(size+1))//|1;

and it still worked.
Sorry about my bad english
Thanks so much for your effecient extension!

If I recall correctly I did that because I use the least significant bit for collisions with regular objects. However ExtremePhysics is set up in such a way that if at least one of the two objects has a collision mask bit in common with the other, a collision will happen, so removing that bit does nothing in this case. However if you removed it as well for the regular objects, they would no longer collide with the terrain.

The (1<<(size+1)) part is used to quickly find all terrain boxes of a certain size.

Write a comment