2
\$\begingroup\$

I am looking for a good method to determine which objects will be considered for collision with other objects.

My current idea is that each object has the following properties:

alwaysCollidesWith = [list of objects that will always trigger a collision check] neverCollidesWith = [lost of objects that will never be considered] teamCollidesWith = [list of objects that will be checked, provided they belong to a different team]

For example: -projectiles never have to be checked for collisions with other projectiles -players are always checked for collisions with players, regardless of team -projectiles are only considered for collisions if they collide with another teams players

Does anyone see any weaknesses with this approach? Can anyone recommend a better approach?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I think another way of doing it is to just have an identifier for each object saying what collision channel it is in and have another field/property that has a list of identifiers for which this object will collide with. You could use an integer/long with some bit operators to just make this an integer for the identifier and another integer for the "list". \$\endgroup\$ Commented Jan 13, 2011 at 1:12
  • \$\begingroup\$ Also, I think it depends on how you want collisions to be resolved. Do you want to do some logic and then resolve the collision? Do you always want collisions resolved first? \$\endgroup\$ Commented Jan 13, 2011 at 1:13
  • \$\begingroup\$ @Omnion: how does that differ from my answer? I honestly can't see the difference. \$\endgroup\$
    – egarcia
    Commented Jan 13, 2011 at 23:02
  • \$\begingroup\$ I don't remember there being an answer when I posted. My comments were based of Farseer (which is based of Box2D). I wasn't trying to copy you or anything of the sort. \$\endgroup\$ Commented Jan 16, 2011 at 15:17

1 Answer 1

7
\$\begingroup\$

The problem I see with your approach is that it doesn't scale very well. For every object, you are storing relations with all the objects that collide with it. If you only have 2 players and a 10 proyectiles, it will work ok. But when that number increases to, say, 20 players and 100 proyectiles, then the number of relations increases exponentially. It'll gradually run more slowly and consume more memory when the number of players increases.

You would be better off by organizing your objects into "groups". And then adding collision/non-collision relationships between each object and those groups. The memory consumption will be slower, and the checks will be faster.

Box2D has a fairly flexible system set up for that.

First, there's categories and masks:

  1. Shapes can have up to 16 "categories" (it's really a 16-bit mask). By default, they are on category "1"
  2. Shapes can also have a "mask" that defines with what categories they can collide. By default, they collide with category "1" only.

Then, there's also groups. A group is an integer.

  1. Two shapes with the same group will always collide, if the group is positive.
  2. Two shapes with the same group will never collide, if the group is negative.
  3. Group rules override mask and category rules.

With these two things, the question "do these two objects collide?", filtering is very fast (a bitmask operation and an integer comparison) and has a very small memory footprint (4 bytes per object).

In your example:

  • Players would have category 1, and mask {1,2} (so they collide with all projectiles by default)
  • Projectiles would have category 2, and mask {1} (they only collide with players)
  • Players and projectile of team 1 would all be in group -1, and team 2 would have the group -2. This way, friendly fire would not happen.

The most recent tutorial that I could find is from 2009 - here it is:

http://www.emanueleferonato.com/2009/10/01/introducing-box2d-filtering/

You can also browse the box2d manual - scroll down until it says "Filtering"

\$\endgroup\$
2
  • \$\begingroup\$ Collision channels are probably a better way to go, they save memory, are simpler, and are more scalable. \$\endgroup\$ Commented Jan 13, 2011 at 22:27
  • 3
    \$\begingroup\$ I'm curious. Care to elaborate? \$\endgroup\$
    – egarcia
    Commented Jan 13, 2011 at 23:04

You must log in to answer this question.