Collision BitArray Bitmask?

Is there a way to use BitArray for a collision BitMask? I understand currently only BitMask32 is supported. Why?

If necessary, where would be a good starting point for modifying Panda3D source such that BitArray is compatible with nodepath.setIntoCollideMask(.), nodepath.setFromCollideMask(.), etc.? Or is this way more complicated than it sounds? :wink:

It seems collideMask.h in the putil folder is the only part of the source code that requires BitMask32 for collision detection. The collisiontraverser.cxx doesn’t require a set number of bits (it even states that in the comments). So, it seems room could be made for types BitArray or BitMask64 without changing too much, no?

Thanks!

It seems like you’re trying to use bitmasks for something they’re not really designed for. Bitmasks are designed to tell the physics engine which KINDS of objects collide with which other kinds of objects, not to uniquely identify each object. If you need find out which object is being collided, you should use setTag and getTag to pass information around, or store the information in the names of the objects (which are recoverable with some work).

The best way to describe what I am doing is with this example in the manual:

http://www.panda3d.org/manual/index.php/Bitmask_Example

The only difference is I have hundreds of objects (not just 3 as in the example). So, for optimal performance, I need hundreds of unique bitmasks. This would be accomplished with BitArray if it were compatible for setting collision masks.

You’re suggestion is currently where I’m at - I am permitted to partitioned my objects into 32 “kinds” as you wrote. For better performance, I want hundreds of kinds defined in the egg file. I have already tried dynamically setting the collision bitmasks. See below about that - it is too slow:

# for now Im no longer interested in collisions with polygon1
polygon1.set_collide_mask(Bitmask32.all_off())

# but instead im interested in collisions with polygon2
polygon2.set_collide_mask(Bitmask32.bit(1))

# here is what I want to collide with polygon2 (for now)
rayInto.setIntoCollideMask(Bitmask32.bit(1))

...

# okay now im interested in polygon1 (for now)
polygon1.set_collide_mask(Bitmask32.bit(1))
polygon2.set_collide_mask(Bitmask32.all_off())
rayInto.setIntoCollideMask(Bitmask32.bit(1))

Thanks for the reply. For more information see my 2nd post above for a similar question I posed about colliding with hundreds of objects in general (no answers yet so I thought I would ask a simpler question)

Okay, I don’t understand what you are doing. Why do you need hundreds of individual bitmasks?

Ok, below is my hardest try at simplifying the matter! :wink:

Imagine the example in the manual (the first link I gave).

In that example there are 3 into collisionSolids and a from collision ray.

Taking that a step further, what if you had 100 into collisionSolids and you still wanted to collide with just one at a time (like in that example where they “switch” the bitmask)?

like in the example, you can assign a unique bitmask for each into collisionSolid (and there are only 3 so that’s easy). The first object has BitMask32.bit(0), then bit(1), bit(2),…,bit(31) - but then there aren’t any more bits available! So how can you do that for 100?

So, I showed my code in the 2nd link I posted for how I did it. It worked. But, it is slow. The fastest way I have found to do it is exactly copying the manual, but, again, you can only do that for up to 32 objects.

Now I have two ideas and am looking for advice on either of them or a better approach altogether:

  1. if collideMask.h allowed for BitMask64 or BitArray I could do this! This is to say, I would have n bits available such that each object would have its own unique bitmask. Currently the methods setCollideMask(.) or setIntoCollideMask(.) require a BitMask32 type. But if it allowed BitArray I would be saved.

  2. This one is going against the grain a bit (I think), but if bitmasks were checked for all bits being equal (rather than any of the bits being equal) this would also solve my problem. Then there would be 2**32 unique bitmasks which is plenty.

That’s not what I meant. I know you’re trying to do that, I just don’t know why. I want to know why you need to check only for collisions against only one of hundreds of objects.

It sounds like you’re trying to be too clever. Are you actually experiencing slowdowns that you know are caused by too many collisions? And if so, how does having a unique bitmask for each individual object fix this?

I am optimizing collision with visible geometry. If you look at the history of my posts (as of today anyway) it has been my primary objective. This is all part of some code I am writing to generate 3D solids from 3D models. Counting the number of times a ray passes through my model tells me if its inside or not, etc.

So, I have models with hundreds of polygons and I have cut down the cost of scanning their surface by something around a factor of 4 or 5. This is done by cutting the 3D model into pieces and colliding with each piece separately such that it has its own unique bitmask (so that you aren’t wasting time on the rest of the geometry).

I can cut a model into 32 pieces and give them each a unique bitmask and that speeds things up nicely. Now I want to cut a model into hundreds of pieces!

Anyway, I know the collision detection is taking a while because I get enormous time savings when i use more appropriate bitmasks. And, the more I chop it the faster it runs.

So, is there another way of removing objects from the collision detection other than bitmasks? Or is there another way of having more uniquely defined collisionmasks?

Does this answer your question? Thanks for your help.

Okay I think I understand now.

What you want to do is make your own collision traverser (this is in the manual somewhere) and run it yourself with traverser.traverse(nodepath) instead of relying on the automatic traversal. base.cTrav will traverse from render, and thus will always check everything in the scene graph. When you traverse it manually, you get to tell it what nodepath to start from, and it won’t check any other parts of the scene graph.

Edit: Or it might behoove you to keep a normal mesh version of your geometry somewhere and just collide against that. That would probably be much faster.

Ok, I see the section in the manual. So I just do:

myTraverser.traverse(geomNodes_piece)

and it only checks for collision with that node eh? I like it! I will have to see how fast this runs.

You mentioned normal mesh? I cant find anything on it. Are you referring to bullet triangle mesh? If so I tried that a way back ago. Bullet has its own query method but it simple returns the first or all object(s) it intersects (whereas I need all the actual surfaces it intersected with).

If you’re creating a complex, 200-mesh object from a 3d model, and you have access to the original model (and it obviously hasn’t been changed since you made the 200-mesh version), then you could skip colliding with the more complex one altogether and just use the original single mesh. They both describe the same volume, so they would both return the same number of in-out collisions.

But if this is infeasible for whatever reason, the custom traverser should work.

Thanks Tober. The custom traverser was the key :smiley:

Panda3D is quite amazing!