Automatic bitmask generation

For a good while I was having trouble whenever I needed to set a collision bitmask in my game because there were just so many different fields manually typing out the bits became tedious.
Fortunately, I was able to come up with this solution where you define a list of possible tags in bitmask_types, and then import and call generate_bitmask with whatever tags you want whenever you need to make a bitmask.

from panda3d.core import BitMask32

bitmask_types = ("world", "water",
                 "red team", "red bones", "blue team", "blue bones",
                 "vr grabable", "point and select"
                 )

assert len(bitmask_types) <= 32

def generate_bitmask(*params):
    newBM = BitMask32()
    assert newBM.is_zero()#Since I'm showing this, a question. Do I need this?
    for param in params:
        if not param in bitmask_types:
            continue
        index = bitmask_types.index(param)
        assert index < 32
        newBM.set_bit(index)
    return newBM
1 Like

Nice. An alternative approach would be to define the types in some global location somewhere like this:

world_mask = BitMask32.bit(0)
water_mask = BitMask32.bit(1)

and then when using them, combine them like so:

set_collide_mask(world_mask | water_mask)

All BitMask32 objects are zero-initialized by default. You can assert that if you wish, but I think this is something you can safely trust without an assert.

3 Likes

I do something similar myself: I define a bunch of bit-indices, and then apply them via the “setBit” method. Something like so:

BIT_PLAYER = 0
BIT_ENVIRONMENT = 1
BIT_ENEMY = 2

MASK_PLAYER_FROM = BitMask32()
MASK_PLAYER_FROM.setBit(BIT_PLAYER)
MASK_PLAYER_FROM.setBit(BIT_ENVIRONMENT)

MASK_PLAYER = BitMask32()
MASK_PLAYER_INTO.setBit(BIT_ENEMY)

MASK_ENVIRONMENT_INTO = BitMask32()
MASK_ENVIRONMENT_INTO.setBit(BIT_ENVIRONMENT)

# And so on...
1 Like