Voxel Graph
A 3D-lattice graph: voxels are first-class nodes, edges represent allowed movement between adjacent voxels, and voxels carry movement costs and blocked / passable status. The 3D analog of GridGraph. Separate from VoxelProjection, which places agents on a lattice but doesn't model the lattice's navigation structure.
Use VoxelGraph for:
3D pathfinding: drones / robots routing through an environment with 3D obstacles (no-fly zones, buildings, warehouse racks with vertical extent).
3D distance fields: precompute "distance to goal voxels" for every voxel via distanceField, then have agents follow the gradient.
3D reachability analysis: which voxels can reach a given altitude / corridor / charging volume.
Edge model:
Each voxel has a
voxelCost, default 1.0. Set via setVoxelCost (and read via voxelCostOf).Edge cost from voxel u to neighbor v is
voxelCost(v) * stepLength, wherestepLengthis:1.0 for orthogonal (face-adjacent) moves
√2 for face-diagonal (edge-adjacent) moves
√3 for body-diagonal (corner-adjacent) moves
Blocked voxels (set via block) have no incident edges and are unreachable from any other voxel.
Boundary semantics:
Bounded (default) — coordinates outside the bounds throw. Voxels on the boundary have fewer neighbors.
Torus (
torus = true) — coordinates wrap on all three axes.
Time complexity:
shortestPath / shortestPathLength: O((V + E) log V) with a binary-heap priority queue (Dijkstra), often dramatically better in practice with a tight A* heuristic (e.g., VoxelHeuristics.OCTILE).
distanceField: O((V + E) log V), one multi-source Dijkstra.
reachableFrom / isReachable: O(V + E) BFS.
Parameters
lattice width (x-axis)
lattice depth (y-axis)
lattice height (z-axis, typically altitude) Corner-cutting (MOORE_26 only):
By default (
allowCornerCutting = false) a diagonal move (face-diagonal √2 or body-diagonal √3) is permitted only when every axis-neighbor it passes between is passable — i.e. for each nonzero offset component, the voxel reached by that component alone must be passable. This prevents agents from clipping through blocked voxels at shared edges/corners.Set
allowCornerCutting = trueto require only that the destination voxel be passable.Has no effect under VON_NEUMANN_6 (only orthogonal moves).
if true, coordinates wrap at boundaries
MOORE_26 (26-way) or VON_NEUMANN_6 (6-way)
if true, diagonal moves ignore the passability of the in-between axis-neighbor voxels (default false)
Constructors
Properties
Number of voxels currently marked as blocked.
The minimum voxel cost across the grid: min(1.0, smallest explicitly-set cost). Equals 1.0 for a uniform grid. Pass to VoxelHeuristics.scaled to keep an A* heuristic admissible when some voxels cost less than 1.0.
Total voxel count (columns × rows × layers).
Functions
Multi-source distance field: for each passable voxel, the shortest-path cost from the nearest source in sources. The canonical use case is "distance from any charging-station voxel" for drone models — compute once at setup, then every drone follows the gradient toward zero in O(1) per step.
Single-source distance field: for each passable voxel, the shortest-path cost from source to that voxel. Unreachable voxels are absent from the result map. Useful when many agents share the same goal; compute the field once via multi-source distanceField, then look up distances per-voxel in O(1).
True if voxel is in bounds (always true on a torus) and not blocked.
Passable neighbors of voxel under the configured movement rule. Excludes blocked voxels and (for non-torus grids) out-of-range voxels.
Set the per-step cost of entering voxel. Must be ≥ 0. Voxels with no explicit cost have cost 1.0 implicitly.
Read the cost of entering voxel. Default 1.0 for voxels not explicitly set.