JoltPhysics
JoltPhysics copied to clipboard
Broadphase and ObjectLayer filters are missing context
I'm currently looking into how to implement collision filtering.
So far I have found these filtering options:
- in the broadphase via ObjectVsBroadPhaseLayerFilter
- pair-wise via 16 bit "layer" information through ObjectLayerPairFilter
- pair-wise via 32 bit "group IDs" and CollisionGroup / GroupFilter
I'm trying to figure out which of these I should use for what. I assume I should use the broadphase filter to separate static/dynamic objects and maybe stuff like "query shapes" (kinematic bodies that are only used for raycasts but not for simulation - e.g. for character hit boxes). Anything else that makes sense to separate in the broadphase? Triggers maybe?
I guess the GroupFilter is the most flexible, but also the slowest one. Not sure exactly when this is really needed, maybe for very special cases like the player object ?
I would like to use the object layer filter to do a quick bitmask check to see whether layer1 objects should collide with layer2 objects. However, the 16 bit layer value is not sufficient for this, so I would need to look up the collision matrix somewhere else.
Unfortunately PhysicsSystem::Init only takes a raw C function pointer for ObjectVsBroadPhaseLayerFilter and ObjectLayerPairFilter, which means all collision filtering information would need to be hard-coded in those functions (or global).
Interestingly, NarrowPhaseQuery::CastRay already does a similar thing, but that one takes BroadPhaseLayerFilter and ObjectLayerFilter as interfaces, so that I can pass along context information.
It would be great if PhysicsSystem::Init would also take interfaces instead.
I guess the GroupFilter is the most flexible, but also the slowest one. Not sure exactly when this is really needed, maybe for very special cases like the player object ?
I found it necessary to provide my own group filter class to disable collisions between jointed objects, as it is not supported out-of-the-box by Jolt.
In general:
- Broadphase layer: each broad phase layer will result in it's own quad tree so you should not have too many of them. A static layer, dynamic layer, query shapes layer, triggers layer is roughly how we have things set up.
- Object layer: An object layer maps to one or more broadphase layers to test against, this allows you to very quickly discard large amounts of bodies.
- Group filter: Most expensive filtering (bounding boxes already overlap), used only during simulation. Allows you fine tune collision e.g. by discarding collisions between bodies connected by a constraint (see GroupFilterTable).
- Body filter: This filter is used instead of the group filter if you do collision queries like CastRay.
And you're right that the ObjectVsBroadPhaseLayerFilter and ObjectLayerPairFilter should have been interfaces. The interfaces in NarrowPhaseQuery used to be function pointers too at some point. I just didn't change these yet. I'll see if I can change this.
Was this change integrated? It looks like it wasn't, but maybe I wasn't looking in the right spot.
No the broadphase and object layer filters still don't have a context, I never got around to implementing it. It should only be a problem though if you have multiple PhysicsSystems in your application that use different layer configurations.