Revision control

+ // 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}
+ */