scene_queries_point_projection
Point projection will either project a point on the closest collider of the scene (QueryPipeline::project_pointRapierContext::project_pointWorld.projectPointr3TryProjectPointQueryPipeline.project_pointQueryPipeline::intersect_pointRapierContext::intersect_pointWorld.intersectionsWithPointr3IntersectPointQueryPipeline.intersect_point
- Example 2D
- Example 3D
let point = Vector::new(1.0, 2.0);
let solid = true;
let max_dist = 12.0;
let filter = QueryFilter::default();
let query_pipeline = world.query_pipeline_with_filter(filter);
if let Some((handle, projection)) = query_pipeline.project_point(
point, max_dist, solid
) {
// The collider closest to the point has this `handle`.
println!("Projected point on collider {:?}. Point projection: {}", handle, projection.point);
println!("Point was inside of the collider shape: {}", projection.is_inside);
}
for (handle, _) in query_pipeline.intersect_point(point) {
// Callback called on each collider with a shape containing the point.
println!("The collider {:?} contains the point.", handle);
}
let point = Vector::new(1.0, 2.0, 3.0);
let solid = true;
let max_dist = 12.0;
let filter = QueryFilter::default();
let query_pipeline = world.query_pipeline_with_filter(filter);
if let Some((handle, projection)) = query_pipeline.project_point(
point, max_dist, solid
) {
// The collider closest to the point has this `handle`.
println!("Projected point on collider {:?}. Point projection: {}", handle, projection.point);
println!("Point was inside of the collider shape: {}", projection.is_inside);
}
for (handle, _) in query_pipeline.intersect_point(point) {
// Callback called on each collider with a shape containing the point.
println!("The collider {:?} contains the point.", handle);
}
- Example 2D
- Example 3D
/* Project a point inside of a system. */
fn project_point(rapier_context: ReadRapierContext) {
let rapier_context = rapier_context.single().unwrap();
let point = Vec2::new(1.0, 2.0);
let max_dist = 4.0; // Colliders further than this distance are ignored.
let solid = true;
let filter = QueryFilter::default();
if let Some((entity, projection)) = rapier_context.project_point(point, max_dist, solid, filter)
{
// The collider closest to the point is attached to `entity`.
println!(
"Projected point on entity {:?}. Point projection: {}",
entity, projection.point
);
println!(
"Point was inside of the collider shape: {}",
projection.is_inside
);
}
rapier_context.intersect_point(point, filter, |entity, _collider| {
// Callback called on each collider with a shape containing the point.
println!("The entity {:?} contains the point.", entity);
// Return `false` instead if we want to stop searching for other colliders containing this point.
true
});
}
/* Project a point inside of a system. */
fn project_point(rapier_context: ReadRapierContext) {
let rapier_context = rapier_context.single().unwrap();
let point = Vec3::new(1.0, 2.0, 3.0);
let max_dist = 4.0; // Colliders further than this distance are ignored.
let solid = true;
let filter = QueryFilter::default();
if let Some((entity, projection)) = rapier_context.project_point(point, max_dist, solid, filter)
{
// The collider closest to the point is attached to `entity`.
println!(
"Projected point on entity {:?}. Point projection: {}",
entity, projection.point
);
println!(
"Point was inside of the collider shape: {}",
projection.is_inside
);
}
rapier_context.intersect_point(point, filter, |entity, _collider| {
// Callback called on each collider with a shape containing the point.
println!("The entity {:?} contains the point.", entity);
// Return `false` instead if we want to stop searching for other colliders containing this point.
true
});
}
The resulting PointProjection also contains the index of the part of the shape the point was projected on
(subshape) for shapes composed of several pieces (compound shapes, triangle meshes, etc.) Just like for ray-casting,
the closure given to RapierContext::intersect_point is given the entity of each collider containing the point, as well
as its Rapier collider, and can return false to stop the search.
- Example 2D
- Example 3D
let point = { x: 1.0, y: 2.0 };
let solid = true;
let proj = world.projectPoint(point, solid);
if (proj != null) {
// The collider closest to the point has this `handle`.
console.log("Projected point on collider ", proj.collider, ". Point projection: ", proj.point);
console.log("Point was inside of the collider shape: {}", proj.isInside);
}
world.intersectionsWithPoint(point, (handle) => {
// Callback called on each collider with a shape containing the point.
console.log("The collider", handle, "contains the point.");
// Return `false` instead if we want to stop searching for other colliders containing this point.
return true;
});
let point = { x: 1.0, y: 2.0, z: 3.0 };
let solid = true;
let proj = world.projectPoint(point, solid);
if (proj != null) {
// The collider closest to the point has this `handle`.
console.log("Projected point on collider ", proj.collider, ". Point projection: ", proj.point);
console.log("Point was inside of the collider shape: {}", proj.isInside);
}
world.intersectionsWithPoint(point, (handle) => {
// Callback called on each collider with a shape containing the point.
console.log("The collider", handle, "contains the point.");
// Return `false` instead if we want to stop searching for other colliders containing this point.
return true;
});
- Example 2D
- Example 3D
R2Vector point = r2Vector(1.0, 2.0);
R2Bool solid = 1;
R2Real max_dist = 12.0;
R2QueryOptions options = r2DefaultQueryOptions();
R2OptionalPointProjection result = r2TryProjectPoint(world, &options, point, max_dist, solid);
if (result.found) {
R2PointProjection projection = result.projection;
// The collider closest to the point has the handle `projection.collider`.
printf("Projected point on collider %u. Point projection: (%f, %f)\n", projection.collider.index,
(double)projection.point.x, (double)projection.point.y);
printf("Point was inside of the collider shape: %u\n", projection.is_inside);
}
// Get the number of colliders containing the point, then copy their handles.
size_t count = r2IntersectPoint(world, &options, point, NULL, 0);
R2ColliderHandle *handles = malloc(count * sizeof(*handles));
count = r2IntersectPoint(world, &options, point, handles, count);
for (size_t i = 0; i < count; i++) {
// Loop on each collider with a shape containing the point.
printf("The collider %u contains the point.\n", handles[i].index);
}
free(handles);
R3Vector point = r3Vector(1.0, 2.0, 3.0);
R3Bool solid = 1;
R3Real max_dist = 12.0;
R3QueryOptions options = r3DefaultQueryOptions();
R3OptionalPointProjection result = r3TryProjectPoint(world, &options, point, max_dist, solid);
if (result.found) {
R3PointProjection projection = result.projection;
// The collider closest to the point has the handle `projection.collider`.
printf("Projected point on collider %u. Point projection: (%f, %f, %f)\n", projection.collider.index,
(double)projection.point.x, (double)projection.point.y,
(double)projection.point.z);
printf("Point was inside of the collider shape: %u\n", projection.is_inside);
}
// Get the number of colliders containing the point, then copy their handles.
size_t count = r3IntersectPoint(world, &options, point, NULL, 0);
R3ColliderHandle *handles = malloc(count * sizeof(*handles));
count = r3IntersectPoint(world, &options, point, handles, count);
for (size_t i = 0; i < count; i++) {
// Loop on each collider with a shape containing the point.
printf("The collider %u contains the point.\n", handles[i].index);
}
free(handles);
The resulting R3PointProjection (the projection field of the result) contains the handle of the collider the point was projected on, the projected
point (in world-space), and whether the original point was inside of that collider (is_inside). If the point is
inside of a shape, solid controls the result just like for ray-casting: with
solid set to 1 the point is its own projection, whereas with solid set to 0 it is projected on the boundary of
the shape. r3TryProjectPoint sets the found field of its result to 0 if no collider is closer than max_dist,
whereas r3ProjectPoint reports this as the R3_NOT_FOUND error. Finally, r3IntersectPoint copies the handles
of the colliders containing the point into a buffer given by the application, as described at the beginning of this
page.
point = (1.0, 2.0, 3.0)
solid = True
max_dist = 12.0
query_filter = rp.QueryFilter()
query_pipeline = world.query_pipeline
projection = query_pipeline.project_point(point, solid, filter=query_filter, max_dist=max_dist)
if projection is not None:
handle, projection = projection
# The collider closest to the point has this `handle`.
print(f"Projected point on collider {handle}. Point projection: {projection.point}")
print(f"Point was inside of the collider shape: {projection.is_inside}")
def on_point_intersection(handle):
# Callback called on each collider with a shape containing the point.
print(f"The collider {handle} contains the point.")
return True # Return `False` to stop the search.
query_pipeline.intersect_point(point, on_point_intersection, filter=query_filter)
QueryPipeline.project_point returns None if no collider is closer than max_dist (which is unbounded if it isn't
given), and the handle of the collider the point was projected on, together with a PointProjection, otherwise. This
PointProjection contains the projected point (in world-space), and whether the original point was inside of that
collider (is_inside). If the point is inside of a shape, solid controls the result just like for
ray-casting: with solid set to True the point is its own projection, whereas
with solid set to False it is projected on the boundary of the shape. QueryPipeline.project_point_and_get_feature
also gives the FeatureId of the part of the shape (vertex, edge, or face) the point was projected on. Finally,
QueryPipeline.intersect_point calls the given function with the handle of each collider containing the point, until
this function returns False.
It is possible to only apply the scene query to a subsets of the colliders using a query filter