Collision Rays - Are they meant to strike geometry only?

I could be wrong about this –

I noticed that geometry serving as visual graphics should have setCollideMask(0) called, because this isn’t set by default.

This is fine and causes no issues, however…

Collision Rays are “odd balls.” They collide with visible geometry even if that geometry isn’t being used as collision geometry.

I ran a test -

I loaded up a small island that had one collision barrier attached as surface collision. I set “setCollideMask(0)” on the visible geometry of the island. I had a Collision Ray strike the island.

NO collision was detected! Of course the visible geometry of the island wouldn’t get detected by the Ray because of the “collide mask” being set to zero, but why not the collision barrier? The collision barrier was not even attached to the island, it was set to render.

From what I can tell, Collision Rays do not collide with collision barriers. I could be wrong… So where am I going wrong?


Am I right?

The collision barrier is much cheaper than the visible geometry, which means faster collision checking for the Ray striking it; but the Collision Ray wants to strike visible geometry only….

That’s kind of odd.

I do believe the Ray will hit a collision object defined within P3D like a Panda collision sphere and so on. It’s just the objects loaded up as collision barriers.

Drwr, what’s going on?

CollisionRays do detect collisions with CollisionNodes (and the CollisionPolygons attached to them) by default.

More specifically, the default collision mask for a GeomNode is GeomNode.getDefaultCollideMask(), which happens to be BitMask32.bit(20) (that is, only bit 20 is on). The default collision mask for a CollisionNode is CollisionNode.getDefaultCollideMask(), which is BitMask32.lowerOn(20) (that is, everything below 20).

The default from mask for a CollisionRay or anything else is also BitMask32.lowerOn(20), which collides with only CollisionNodes, not with visible GeomNodes.

You can change either of these masks to change this default behavior, of course.


By bitMask20, do you mean setCollideMask(0x20)?

So, in order the stop my Collision Ray from colliding with the test island, I should set the betMask of the island (geometry) higher than 0x20?

So loaded collision barriers are also 0x20 I guess…

Actually, setting the bitMask to 0 will stop it. What I want to do is get the Ray to collide with my loaded Object, which happens to be a collision barrier.

I tried BarrierObject.setCollideMask(0x20), but that didn’t work.

No, I mean BitMask32.bit(20), which is a very different thing than BitMask32(0x20) (which is what you are implicitly getting with setCollideMask(0x20)).

Bit 20 means the 20th bit from the right, which is another way of saying BitMask32(0x10000). Value 0x20 is a hex value with just one bit, bit 5, enabled. This is another way of saying BitMask32.bit(5).

>>> print BitMask32.bit(20)
 0000 0000 0001 0000 0000 0000 0000 0000
>>> print BitMask32(0x20)
 0000 0000 0000 0000 0000 0000 0010 0000

The difference between these two constructors is very important to understand. BitMask32.bit(20) constructs a bitmask with just bit 20 set. BitMask32(0x20) constructs a bitmask with the numeric value 0x20. These are completely different things.

Since setCollideMask() accepts a BitMask32, when you pass it the integer value 0x20 instead, Panda automatically assumes you meant to call the implicit BitMask32 constructor that takes a simple integer value, so setCollideMask(0x20) is the same thing as calling setCollideMask(BitMask32(0x20)).

>>> np.setCollideMask(0x20)
>>> print np.getCollideMask()
 0000 0000 0000 0000 0000 0000 0010 0000

And to clarify the default values:

>>> print GeomNode.getDefaultCollideMask()
 0000 0000 0001 0000 0000 0000 0000 0000
>>> print CollisionNode.getDefaultCollideMask()
 0000 0000 0000 1111 1111 1111 1111 1111

See? The default GeomNode collide mask is only bit 20 on. The default CollisionNode collide mask is all bits below bit 20 on.

The only thing special about bit 20 is that it is the only default bit that is enabled for GeomNodes, which is normally what you don’t want to be colliding with. But it does mean that if you set bit 20 as your “from” collide mask, you will be testing collisions with any GeomNodes in the world (well, except the ones that you have explicitly changed the into collide mask for).

Bits below 20 are generally free for your use for normal purposes. Normally, you would use a collide mask with bits entirely below 20.

Bits above 20 aren’t specifically allocated for anything right now, so you could use them if you wanted, but we reserve the right to declare them for special purposes within Panda in the future, so it’s probably best if you don’t use them.


So instead of coding ObjBarrier.setCollideMask(0x10), I should code, ObjBarrier.setBitMask32.bit(20)?



No. I’m trying to explain to you how the system works, not precisely how to solve your particular problem.

I don’t know how to solve your particular problem, because you haven’t told me enough about precisely what you’re doing. I’m trying to give you enough information to figure it out for yourself, though.

Let me summarize what I’m telling you:

  1. CollisionRays will test for intersection with CollisionNodes by default.

  2. CollisionRays will not test for intersection with GeomNodes by default.

  3. You can change this behavior for a particular CollisionRay, to make it test for intersection with anything you like. You do this by setting the collide masks on one or the other, or both, so that they have at least one bit in common.

3a) Precisely what values you should set are up to you, as long as you make the things you want to test for intersection have at least one bit in common, and the things you do not want to test for intersection not have any bits in common.

  1. To help you decide what bits you can use for this purpose, you should be aware of the fact that bit 20 has a special meaning and should not be used. The bits above bit 20 may have a special meaning in the future and probably should not be used. The bits below bit 20 have no special meaning and may be used for whatever purpose you like.


Problem Solved -

Panda3D collision rays were not meant to handle objects loaded up as collision barriers, but rather to collide with a mesh that has a higher polygon count, thus increasing collision calculation time, thus needlessly destroying fps.

Work around -

Disable the collision ray or remove it from the Col Trav when collision detection is not needed from it, ASAP, and re-enable it for collision/picking functionality and disable again, ASAP.