scene_queries_filters
It is common to exclude some colliders from being considered by a scene query. For example, a ray-cast performed for a
character controller will usually want to skip the character itself. Sometimes, we may even want it to ignore both the
character and any collider attached to a dynamic rigid-body, and ignore all sensors. To allow this filtering, most
scene queries take an R3QueryOptions argument that lets you describe what needs to be excluded. In particular the fields of its filter (an R3QueryFilter), and its predicate:
flagsallows you to discard whole families of colliders based on their types or their parent types (e.g. exclude all sensors and all the colliders attached to a dynamic rigid-body).groupsis used to apply the collision group rules for the scene query. The scene query will only consider hits with colliders with collision groups compatible with this collision group (using the bitwise test described in the collision groups section).exclude_collideris the handle of one collider the query must ignore.exclude_rigid_bodyis the handle of one rigid-body with attached colliders the query must ignore.predicateis a user-defined callback to apply any filtering rule. This can be used if the other filtering options above are not flexible enough.
The query options are initialized by r3DefaultQueryOptions, which doesn't exclude any collider. The flags are a
combination of the R3_QUERY_EXCLUDE_* constants (e.g. R3_QUERY_EXCLUDE_SENSORS), or one of the shortcuts
R3_QUERY_ONLY_DYNAMIC, R3_QUERY_ONLY_KINEMATIC, and R3_QUERY_ONLY_FIXED. The groups are only applied if the
use_groups field is set to 1. The exclude_collider and exclude_rigid_body fields are set to an invalid handle
(e.g. R3_INVALID_COLLIDER_HANDLE) to exclude nothing. Finally, the predicate is a callback called for each collider
that passed the other filtering rules: it returns 0 to exclude that collider. It is given the userData field of the
query options, a read-only access to the world (an R3ReadContext to be given to the r3ReadCollider_* and
r3ReadRigidBody_* functions), and the handle of the collider. Other scene queries can be performed from this
callback, but the world cannot be modified until the outer query returns.
Here is an an example of usage of the query filters with ray-casting:
// The predicate is called for each collider that passed the other filtering rules.
// Returning 0 excludes the collider from the scene query.
static R2Bool RAPIER_CALL user_data_predicate(void *user_data, const R2ReadContext *read,
R2ColliderHandle handle) {
(void)user_data;
return r2ReadCollider_UserData(read, handle).low == 10;
}
static void query_filter_section(const R2World *world, R2RigidBodyHandle player_handle) {
R2Vector ray_origin = r2Vector(1.0, 2.0);
R2Vector ray_dir = r2Vector(0.0, 1.0);
R2Real max_toi = 4.0;
R2Bool solid = 1;
R2QueryOptions options = r2DefaultQueryOptions();
options.filter.flags = R2_QUERY_EXCLUDE_DYNAMIC | R2_QUERY_EXCLUDE_SENSORS;
options.filter.exclude_rigid_body = player_handle;
options.filter.use_groups = 1;
options.filter.groups.memberships = 0x0001 | 0x0002; // Groups 1 and 2.
options.filter.groups.filter = 0x0001; // Group 1.
options.filter.groups.test_mode = R2_GROUPS_AND;
options.predicate = user_data_predicate;
options.userData = NULL; // Given to the predicate as its first argument.
R2RayToi toi = r2CastRayToi(world, &options, ray_origin, ray_dir, max_toi, solid);
if (toi.found) {
// Handle the hit.
}
}