Scene queries allow you to specify a geometric object and perform a query if that object intersects or overlaps any physics object in the scene. Most queries also return detailed information about the intersection. All queries are performed through the global @ref bs::Physics "Physics" interface, accessible through @ref bs::gPhysics "gPhysics()".
Here is a short example of a basic query, to give you a better idea:
// Ray starting at origin, traveling towards negative Z
Vector3 origin(0, 0, 0);
Vector3 direction(0, 0, -1);
Ray ray(origin, direction);
PhysicsQueryHit hitInfo;
// Cast a ray into the scene and return information about first object hit
if(gPhysics().rayCast(ray, hitInfo))
{
HCollider hitCollider = hitInfo.collider;
String hitSceneObjectName = hitCollider->SO()->getName();
Vector3 contactPoint = hitInfo.point;
gDebug().logDebug("Hit " + hitSceneObjectName + " at point " + toString(contactPoint));
}
There are two major types of queries:
Casts are types of queries in which you provide a shape, origin point and a direction, and the system check if the shape intersects anything along the way.
Cast can be used with different objects (shapes):
Note that only convex meshes are supported when performing mesh casts. Read the physics mesh manual to learn about convex meshes.
They can also be categorized by the type of values they return:
As the name implies, these type of queries perform a cast and then return information about all hit objects. Relevant methods are:
They all share a common interface, where as the first parameter they accept a shape with its starting position and orientation, travel direction, and finally an optional maximum range. They return an array of @ref bs::PhysicsQueryHit "PhysicsQueryHit" objects.
// Sphere centered at origin with radius 0.5
Sphere sphere(Vector3(0, 0, 0), 0.5f);
// Check negative Z direction
Vector3 direction(0, 0, -1);
// Find all objects intersecting the sphere traveling in the specified direction
Vector<PhysicsQueryHit> hits = gPhysics().sphereCastAll(sphere, direction);
for(auto& entry : hits)
{
HCollider hitCollider = entry.collider;
String hitSceneObjectName = hitCollider->SO()->getName();
Vector3 contactPoint = entry.point;
gDebug().logDebug("Found hit with " + hitSceneObjectName + " at point " + toString(contactPoint));
}
PhysicsQueryHit object contains information about each individual hit, and it contains:
Closest hit casts are nearly identical to all hit casts, with the main difference is that they return a boolean value if a hit occurred or not, and output a single PhysicsQueryHit object. Hit information returned always concerns the closest found hit.
Checking for closest hit is cheaper than checking for them all, and is usually adequate for most applications. Relevant methods are:
They also share a common interface where as the first parameter they accept a shape with its starting position and orientation, travel direction, reference to a PhysicsQueryHit object to receive the results, and finally an optional maximum range. They return a boolean value that returns true if anything was hit.
// Axis aligned box centered at origin with extents 0.5 in all directions
AABox box(Vector3(-0.5f, -0.5f, -0.5f), Vector3(0.5f, 0.5f, 0.5f));
// Check negative Z direction
Vector3 direction(0, 0, -1);
// Find closest object intersecting the box traveling in the specified direction
PhysicsQueryHit hitInfo;
if(gPhysics().boxCast(box, direction, hitInfo))
{
HCollider hitCollider = hitInfo.collider;
String hitSceneObjectName = hitCollider->SO()->getName();
Vector3 contactPoint = hitInfo.point;
gDebug().logDebug("Found hit with " + hitSceneObjectName + " at point " + toString(contactPoint));
}
Finally, any hit casts are the simplest (and cheapest) of them all. They simply return a boolean value if a hit occurred or not. They do not return any further information about the hit.
Relevant methods are:
@ref bs::Physics::convexCastAny "Physics::convexCastAny()"
// Ray starting at origin, traveling towards negative Z
Vector3 origin(0, 0, 0);
Vector3 direction(0, 0, -1);
Ray ray(origin, direction);
// See if the ray intersects anything while traveling in the specified direction
if(gPhysics().rayCastAny(ray))
gDebug().logDebug("Found hit!");
Overlap queries simply check if an object standing still at a specific position/orientation overlaps any other objects.
Overlaps can be used with different shapes:
They can also be categorized by the type of values they return:
These overlap methods return an array of Collider%s consisting of all the objects the provided shape is currently overlapping. Relevant methods are:
They all share a common interface. As input they take a shape with its starting position and orientation, and return an array of overlapping objects.
// Sphere centered at origin with radius 0.5
Sphere sphere(Vector3(0, 0, 0), 0.5f);
// Find all objects overlapping the sphere
Vector<HCollider> overlaps = gPhysics().sphereOverlap(sphere);
for(auto& entry : overlaps)
{
String overlappingSceneObjectName = entry->SO()->getName();
gDebug().logDebug("Found overlap with " + overlappingSceneObjectName);
}
This is a set of overlap methods that returns only a boolean value if the overlap occurred or not, without a list of colliders that are overlapping. This is cheaper than querying for all overlaps. The relevant methods are:
@ref bs::Physics::convexOverlapAny "Physics::convexOverlapAny()"
// Sphere centered at origin with radius 0.5
Sphere sphere(Vector3(0, 0, 0), 0.5f);
// Check if sphere overlaps anything
if(gPhysics().sphereOverlapAny(sphere))
gDebug().logDebug("Found overlap!");