0

How do short int based masks work in c++ (for example ones in Bullet)?

I look at Bullets

CollisionFilterGroups { 
  DefaultFilter = 1, 
  StaticFilter = 2, 
  KinematicFilter = 4, 
  DebrisFilter = 8, 
  SensorTrigger = 16, 
  CharacterFilter = 32, 
  AllFilter = -1 
}

And see that all values are degrees of 2 and I know that:

short is signed integer that takes 2 bytes to store and is from −32,768 to +32,767.

But how to create my own groups: how to calculate mask intersections?

For example how to create in addition to CollisionFilterGroups something like:

MyCollisionFilterGroups { 
  Cubes= ?,
  Boxes= ?, 
  Spheres= ?
}

Where

  • We want "planes" not to collide ("see") with "planes", "boxes" and "spheres"
  • We want "boxes" to collide with other "boxes" and "spheres"
  • We want "spheres" not to collide with "spheres" yet collide with "boxes"
myWallJSON
  • 9,110
  • 22
  • 78
  • 149

3 Answers3

2

Basically, if it is a power of two, that means than in the binary representation there is only one 1 bit, the rest being 0, like this: 1 = 1, 2 = 10, 4 = 100, 8 = 1000, 16 = 10000 and so on. Now lets say that a = 1, b = 2, c = 4, d = 8, e = 16, f = 32. if you have a number and you want to see if it has a and e you make a mask like this: a|b(or)...this will result in 10001 binary representation.

Lets say the number you want to test for a and e is X. The following statement is true only if X contains a and e: X&(a|e) == X, that is X and (a or e) equals X.

For a first example X is 11001, that is contains a and e. 11001 & 10001 will be 10001, so it is true, thus you have found out that X contains a and e.

Second example: X is 100111, that is contains a, but does not contain e. when you "and" it with a|e(10001), it will result in 000001, which is not equal to X, thus X does not contain.

Now for initializing, if you want a number to contain a,c,e you write: X=a|c|e

It all comes down to the binary representation of the numbers. In the example that you wrote there is also a -1, which in binary representation is 1111..11, that means it covers everything.

Hope this helps

Cristi M
  • 446
  • 4
  • 13
1

Your question is unclear, but I think you're looking to set category and mask bits for the objects in your simulation:

MyCollisionFilterGroups { 
    Plane= 64,
    Box= 128, 
   Sphere= 256
}

Plane, category bits = Plane, Mask = 0

Box, category bits = Box, mask = Box + Sphere (or Box | Sphere)

Sphere, category bits = Sphere, mask = Box

In a nutshell, create power of two for each filter group, set the category mask for each object to the group enum, and set its mask to the enum of the object types you want it to collide with (or 0 to collide with nothing).

Josh Greifer
  • 3,151
  • 24
  • 25
0

Not sure how Bullet specific works, but the idea is this:

Each object have a collision group flag and a collision mask. A collision group is a classifier of your object (what kind of object). A collision mask is all groups (classifiers) that your object collide against with (generally it starts as 0xffff, meaning it collides with everything)

In the collision test, it goes like this:

if( obj->group & otherObj->mask
    &&
    obj->mask & otherObj->group )
 ..check collision..

If you want to create new groups, (i dunno how bullet works or allow this), create one with just one bit set, and that is not already set (the ones you show in your post), I dont like to write it with ints, is confuse, I prefer bit shifts:

DefaultFilter = 1 equals (1<<0)
StaticFilter = 2, equals (1<<1)
KinematicFilter = 4, equals (1<<2)
DebrisFilter = 8, equals (1<<3)
SensorTrigger = 16, equals (1<<4)
CharacterFilter = 32, equals (1<<5)
AnewGroup_Box = (1<<6),
AnewGroup_Sphere = (1<<7)

Up to the number of bits in a short (16 mostly). To set with what groups your object (not group) collides with, simply combine the groups in the mask:

myObj->mask = AnewGroup_Box | StaticFilter | DebrisFilter; // groups obj will collide

Im not sure how Bullet works, thou..

Hope this helps, correct me if Im wrong.

Icebone1000
  • 1,231
  • 4
  • 13
  • 25