Collision group & mask confusion?

Post Reply
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Collision group & mask confusion?

Post by SynapticBytes »

Hi All,

I'm trying to confirm exactly how many and which bits I can use for collision masks & groups. The Wiki says 16 bits, and the code seems to use short ints, so that sounds correct, but the bullet manual says 32 bits are available?

Also, I though the collision flags on a body where separate from the collision group & mask values, but I saw other posts which state the first 6 bits of the mask are used by the body flag values already in use.

So, what is correct? Are there 16 bits available (well, 14 really since a short is signed, losing one, and you want to reserve the value 1 for the default group), 32 bits available, and are the first 6 bits used by in conjunction with the body flags or not?

Thanks.
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Collision group & mask confusion?

Post by xexuxjy »

I agree it is a bit confusing, as you say the code defines things as short int so that would give you the 16 bits. I think the main confusion is the difference between the m_collisionFlags on btCollisionObject (CF_*) and the group and mask values that exist in the broadphase proxy. From what I can remember you should able to to use the full range of the broadphase proxy groups and masks, but shouldn't try and replace the CF_* values.

Hope that makes a little bit of sense....
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: Collision group & mask confusion?

Post by MaxDZ8 »

All the code I've seen in the broadphase mainly involved bit-testing only, therefore there's no such thing as a sign bit so there's no "losing one". It's really a 16-bit mask, not a number.
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Re: Collision group & mask confusion?

Post by SynapticBytes »

Thanks. So the m_collisionflags are separate from the collison group and collision mask values, which are part of the broadphase structure.

The sign bit is important, as setting the mask for all bits uses the value of -1, which in binary two's compliment format is 1111111111111111. So the most significant bit indicates the sign value, and to avoid complexity in calculating the mask including that bit, I'm just suggesting it's easier to consider it "reserved", but maybe I have something wrong there.

Then given the system uses 1 as the default group, I'd say a safe user range would be bits 2-15, which is 14 mask values. That's my understanding anyway.
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Re: Collision group & mask confusion?

Post by SynapticBytes »

OK so now I'm not so sure again. I found these enums in the broadphaseproxy.h

00091 enum CollisionFilterGroups
00092 {
00093 DefaultFilter = 1,
00094 StaticFilter = 2,
00095 KinematicFilter = 4,
00096 DebrisFilter = 8,
00097 SensorTrigger = 16,
00098 CharacterFilter = 32,
00099 AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger

It says they're optional, but if you use your own group 2 for example, isnthat going to ovwrite some staticfilter test elsewhere?

Also while looking at it, what the heck is a DebrisFilter?
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: Collision group & mask confusion?

Post by MaxDZ8 »

You're trying to pull a mountain out of a molehill.
Those are not "filters" of any kind (in the sense they have no special logic associated). They are magic numbers. They don't do anything by themselves. Specifically, they are used in btOverlappingPairCache.h, LN109.

Code: Select all

SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
	{
		if (m_overlapFilterCallback)
			return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);

		bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
		collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
		
		return collides;
	}
So why are those defined?
For convenience mostly. Bullet itself does not use them if not as default values to fill the gaps when you don't specify a valid mask (which is a pretty dumb thing to do IMHO).

KinematicFilter, DebrisFilter and SensorTrigger are especially useless as they don't appear in any file besides btBroadphaseProxy.h. I guess they're here for historical reasons.

Those values are only used to convey some extra information to the programmer who is writing code. If they read "CharacterFilter" they guess this group is used for "characters" (whatever that means in your system). Personally I think predefined groups could go.
Internally, bullet has no special mangling of a bit instead of another. None I stumbled on at least. So when you ask if they overwrite something... what is your fear exactly?
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Re: Collision group & mask confusion?

Post by SynapticBytes »

OK thanks. I'm guess I'm just concerned I'm missing something, and in future a function will be implemented that uses these values and suddenly starts overwriting or overriding any groups I've used, using the first 6 bits.

As I'm writing a plugin for ShiVa3D users, I don't want to tell them now they are free to use the first 6 bits and then later go and say sorry, rewrite all your code to bits above those.
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: Collision group & mask confusion?

Post by MaxDZ8 »

I don't know anything about Shiva3D but my sincere opinion as a middleware author is that if you're forcing your users to think at bit-masks, either your middleware is super-low-level, or you're doing things wrong.
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Re: Collision group & mask confusion?

Post by SynapticBytes »

Shiva3D is a game engine like Unity and all the others out there, and from what I've seen, they all use bit masks for collision masking.

I could create 16 constants, so they don't need to calculate the value of each bit to set, or setup an array of values to index into, but that bloats the codebase for what I would consider is a basic programming construct that anyone writing games should understand.

*EDIT*

Actually I've thought about it a bit more, and you may have a point in that direct bit setting could be simplified, so I have added a mask set/get function so at least they only need to specify the bit location that want to toggle, instead of calculating the binary value and doing the bitwise operators.
kijoshua2
Posts: 7
Joined: Wed Mar 06, 2013 9:12 pm

Re: Collision group & mask confusion?

Post by kijoshua2 »

The tricky part that caught me off guard is that many of the callback structures defined in Bullet also use those default filters and groups. So if you were to use RayResultCallback or any of its derivatives for example, note that its filter group is initialized to DefaultFilter for some reason (why not AllFilter?). RayResultCallback::m_collisionFilterGroup is a public data member at least, but it is perhaps easy to miss since there is no argument for it in the constructor. You can also derive from it yourself and override needsCollision.

Overall, it does seem that none of those predefined values are used internally in such a way that forces you to use them. I'll go update the wiki to make it clearer.
agoose77
Posts: 4
Joined: Sun Feb 10, 2013 3:41 pm

Re: Collision group & mask confusion?

Post by agoose77 »

To my mind, you should write your own collision group / mask functionality using broadphase callbacks rather than use Bullet's
Post Reply