Revision control

Copy as Markdown

// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example queries
\ingroup quick3dphysics-examples
\title Qt Quick 3D Physics - Queries Example
\examplecategory {3D}
\brief Demonstrates the scene query methods of PhysicsWorld.
\image queries-example.webp {Screenshot of the queries example}
Qt Quick 3D Physics provides a set of synchronous spatial query methods directly on
the \l PhysicsWorld node. These let you evaluate physical intersections, cast rays,
test volumetric paths, and find overlapping collision bodies on demand, without
waiting for a contact callback.
The example demonstrates all eight query methods in an interactive scene, split into
probes that push bodies around and scanners that only report whether the space ahead
is clear. Move with \c WASD, drag with the mouse to look, press \c {1} to \c {8} to
pick a query, and press \c Space to run it.
\section1 Overview of Query Types
Spatial queries are divided into three shape geometries and three operational modes:
\table
\header
\li Query Geometry
\li Test Mode (\c bool)
\li Single Hit Mode (\c locationHit)
\li Multi Hit Mode (\c {list<locationHit>})
\row
\li \b Raycast (Infinitesimal Line)
\li \c testRaycastQuery()
\li \c singleRaycastQuery()
\li \c multiRaycastQuery()
\row
\li \b Sweep (Volume Extrusion)
\li \c testSweepQuery()
\li \c singleSweepQuery()
\li \c multiSweepQuery()
\row
\li \b Overlap (Stationary Volume)
\li \c testOverlapQuery()
\li N/A
\li \c multiOverlapQuery()
\endtable
\section2 Key Query Parameters
All query methods share two filtering parameters:
\list
\li \c includeStatic (\c bool): Includes \l StaticRigidBody nodes in the query.
\li \c includeDynamic (\c bool): Includes \l DynamicRigidBody nodes in the query.
\endlist
\note At least one of \c includeStatic or \c includeDynamic must be \c true. If both
are \c false, the query returns \c false or an empty list immediately.
\section1 Understanding queryHit and locationHit
Overlap queries return \l queryHit, which carries the \c body and \c shape that were
hit. Raycast and sweep queries return \l locationHit, which adds the geometric fields:
\table
\header
\li Property
\li Type
\li Description
\row
\li \c body
\li \c PhysicsNode
\li The physics body hit by the query.
\row
\li \c position
\li \c vector3d
\li World-space coordinates of the exact collision impact point.
\row
\li \c normal
\li \c vector3d
\li Surface normal vector at the impact point (facing outward).
\row
\li \c distance
\li \c real
\li Distance along the query ray or sweep from the origin to the hit position.
\row
\li \c shape
\li \c CollisionShape
\li The specific collision shape that was hit.
\endtable
A query that hits nothing returns a hit whose \c body is \c null. Because every body
in the scene has an associated node, \c {hit.body === null} is the reliable test for a
miss; the \c distance of a missed hit is \c 0 and carries no meaning.
\section1 Setup in PhysicsWorld
To run queries you need a running \l PhysicsWorld. Volume-based queries, meaning sweeps
and overlaps, additionally need a \l CollisionShape to use as the query volume.
\snippet queries/main.qml physics-world-setup
A sweep or overlap query runs the shape at its current scene transform, so the shape's
position and rotation define where the query happens. The query shapes here have no
parent node, so the example assigns their \c position directly before each query.
The query shape must be a \l BoxShape, \l SphereShape, \l CapsuleShape or
\l ConvexMeshShape. See \l {Qt Quick 3D Physics Scene Queries} for the behavior that
all scene queries share, including how they treat trigger bodies and triangle meshes.
\section1 Raycast Queries
Raycast queries project an infinitely thin ray from an origin along a direction vector,
up to a maximum distance.
All three raycast modes in the example start from the same place. The player's own
collider is an ordinary hit candidate, so a ray starting at the player's center would
hit the player's own capsule at distance \c 0 before reaching anything else. To avoid
that, the example pushes the origin out in front of the player before casting:
\snippet queries/main.qml probe-origin
\section2 Single Raycast
\c singleRaycastQuery evaluates the line segment and returns the \e closest body hit.
The example uses it for a precise, instant probe: it casts along the player's facing
direction, draws a thin tracer out to whatever it hit (or to the full range on a miss),
and pushes the body it found.
\snippet queries/main.qml mode-single-raycast
Note that the impulse is only applied to a \l DynamicRigidBody. The query also returns
the static arena and the player's own character controller, neither of which can take
an impulse.
\section2 Multi Raycast
\c multiRaycastQuery pierces through geometry and returns \e all bodies along the ray
path, not just the nearest. The example uses it to push an entire column of bodies at
once, so the tracer always spans the full range.
\snippet queries/main.qml mode-multi-raycast
\note Results from multi-hit queries are \b unsorted. If you need depth order, sort the
returned list by \c hit.distance yourself.
\section2 Test Raycast
\c testRaycastQuery is a boolean line-of-sight check. It returns as soon as \e any
obstacle intersects the ray and never builds hit structures, which makes it the
cheapest of the three. The example runs it every frame as a scanner and colors the
tracer according to whether the path is clear.
\snippet queries/main.qml mode-test-raycast
\section1 Sweep Queries
Sweep queries cast a 3D volume (\l CollisionShape) along a direction vector, which is
what you want for thick projectiles, wide probes, or checking whether a character fits
through a gap.
\section2 Single Sweep
\c singleSweepQuery moves a shape along a vector and reports the first body it touches.
The example sweeps a \l SphereShape, so unlike the raycast it connects with anything
within the sphere's radius of the path rather than only what is exactly on the line.
\snippet queries/main.qml mode-single-sweep
\section2 Multi Sweep
\c multiSweepQuery sweeps a shape, here a \l BoxShape, and collects every body along
the path. The example renders the swept corridor as a translucent box so the volume
being tested is visible.
\snippet queries/main.qml mode-multi-sweep
\section2 Test Sweep
\c testSweepQuery reports whether a volumetric corridor is free of obstructions. The
example runs it every frame as a clearance scanner, casting the sphere ahead of the
player and coloring a ghost volume at the far end by the result.
\snippet queries/main.qml mode-test-sweep
\section1 Overlap Queries
Overlap queries evaluate a stationary region of space using a \l CollisionShape,
without extruding it along a path.
\section2 Multi Overlap
\c multiOverlapQuery returns all bodies currently inside or intersecting the query
volume. The example places a sphere some distance ahead of the player and pushes
everything inside it outward, using each body's position relative to the sphere's
center to compute a direction.
\snippet queries/main.qml mode-multi-overlap
\section2 Test Overlap
\c testOverlapQuery reports whether any body occupies the given volume. It returns as
soon as it finds one and builds no hit data, which makes it the cheapest of the overlap
queries. The example uses it as an occupancy check on the space ahead of the player,
the kind of test you would run before spawning something there.
\snippet queries/main.qml mode-test-overlap
\sa PhysicsWorld, {Qt Quick 3D Physics Scene Queries}
*/