Queries (sim-free)
Ask spatial questions — "is this inside that zone?", "are these points touching?", "what does this ray hit?" — without running a full simulation.
Sometimes you don't want physics. You don't need gravity, mass, or a solver chewing every frame — you just want to ask a question about where things are and react to the answer. That's what the Query nodes are for. They're fast, they run on ordinary graph geometry, and they're perfect for game-style logic: pickups, kill zones, checkpoints, doors, contact sparks, and aiming.
Trigger zones
The query.trigger node answers the simplest spatial question: which of these elements are inside that region?
You feed it a set of points (your elements) and a zone. The zone can be almost anything — a primitive shape, an Analytic shape, a mesh, a raster, or a Distance Field — DNA converts it to a region automatically. Anything inside comes out the inside pin; every element also gets tagged with its signed @distance to the zone's surface, so you can fade, scale, or colour by proximity.
Because the zone is evaluated wherever your query points are, a moving zone is free — animate it, drive it from a Pointer, and the test follows along with no extra cost.
| Parameter | Type | Default |
|---|---|---|
elements | OneOf([Collection]) | — |
zone | OneOf([FieldOf(Sdf)]) | — |
radius | Number | 0 |
track_identity | Boolean | false |
opacity | Number | 1 |
Enter / exit events
Turn on Track identity and the Trigger remembers what was inside last frame. As long as your elements carry an @id (points from sop.scatter or a particle sim do), you get three extra streams:
entered — crossed in this frame
staying — was inside last frame and still is
exited — left this frame (these carry the element's last-known row, so even a despawned object still surfaces here)
This is exactly what you want for a pickup that fires once on entry, or a checkpoint that triggers a sound the moment a runner crosses it.
The radius parameter controls how the test is done. Leave it at 0 for a pure point test (the element's centre must be inside). Raise it to treat each element as a little sphere — handy when a point should count as "inside" the moment its edge touches the zone.
Contact detection
query.collision_detect is the next step up: instead of a yes/no region test, it reports which points of one piece of geometry are touching the surface of another — and hands you the contact detail.
Feed it a mesh as geometry_a and a surface as geometry_b (again, mesh / Analytic shape / raster / Distance Field, all auto-converted). Any of A's points within the threshold distance of B's surface come out the contacts pin, each carrying:
@contact_dist — signed penetration depth (negative means the point is inside B)
@contact_N — the surface normal at the contact, so you can orient sparks, decals, or splashes to lie flat on the surface
Use it to spawn effects exactly where things touch, snap geometry to a surface, or build your own custom contact response — all without registering anything in a solver.
| Parameter | Type | Default |
|---|---|---|
geometry_a | GpuGeometry | — |
geometry_b | OneOf([FieldOf(Sdf)]) | — |
max_pairs | Number | 10000 |
threshold | Number | 0.100 |
track_identity | Boolean | false |
opacity | Number | 1 |
Collision Detect tests points against a surface, not full triangle-against-triangle intersection. It's a proximity check: a point counts as touching when it's close enough to B's surface. That's the right tool for the vast majority of gameplay and effects work, and it's far lighter than true mesh intersection. It also supports the same Track identity enter/exit streams as the Trigger.
Raycasts and overlaps
Physics Query casts rays and sweeps shapes against the colliders you've set up in a physics world. It's the node for aiming, line-of-sight, ground-snapping, and "what's near this point?" lookups.
It runs four kinds of query:
Raycast — fire a ray from an origin in a direction; get back the first surface it hits.
ShapeCast — sweep a ball or box along a direction instead of an infinitely thin ray (good for "can this character fit through here?").
PointQuery — find the closest collider surface to a point.
Overlap — find everything within a radius of a point.
Every query reports a rich set of outputs: whether it hit, the hit point, the hit normal, the distance, which body was hit, an overlap count, and whether the origin started inside a collider. Wire those into expressions or other nodes to drive your logic.
| Parameter | Type | Default |
|---|---|---|
world_id | String | "default" |
query_type | String | "Raycast" |
origin_x | Number | 0 |
origin_y | Number | 100 |
origin_z | Number | 0 |
direction_x | Number | 0 |
direction_y | Number | -1 |
direction_z | Number | 0 |
max_distance | Number | 1000 |
query_shape | String | "Ball" |
query_radius | Number | 5 |
query_half_x | Number | 5 |
query_half_y | Number | 5 |
query_half_z | Number | 5 |
opacity | Number | 1 |
Physics Query tests against the colliders registered in a physics world (the static colliders and bodies you've set up), not against arbitrary graph geometry. If you want to query against a loose mesh or shape with no solver involved, reach for Trigger or Collision Detect instead — they take any geometry directly.
Which one do I want?
"Is it inside?" → query.trigger. Boolean region test with proximity distance and enter/exit events.
"Are these touching, and where?" → query.collision_detect. Contact points with penetration and surface normal.
"What does this ray hit?" → Physics Query. Raycasts, shape sweeps, and overlaps against a physics world.
All three are sim-free in spirit — Trigger and Collision Detect don't need a solver at all, and Physics Query reads a world without stepping it — so they're cheap to scatter throughout a graph for interactive, game-style behaviour.
See also
Simulation — the full simulation toolkit
Distance fields & volumes — how zones and surfaces are measured
Analytic shapes — Analytic shapes as query regions
Fields & sampling — sampling a field at points
Triggers, events & booleans — enter/exit are events; how triggers differ from booleans
The Expression language — reacting to query outputs with Expressions