cvkg-spatial
Canonical spatial indexing for the CVKG platform. Provides three broad-phase spatial query structures — Quadtree, Bvh, and SpatialHash — used by Scene, Physics, Flow, and Layout.
Boundaries
This crate provides spatial indexing only. It does not own scene data, physics bodies, or layout logic. It accepts axis-aligned bounding rects (cvkg_core::Rect) and returns candidate matches. Exact intersection testing is always the caller's responsibility.
All three structures are designed for per-frame rebuild patterns: insert items, query, then clear and rebuild next frame. There is no incremental update API.
Dependency graph
graph LR
cvkg-spatial --> cvkg-core
cvkg-spatial --> serde
cvkg-spatial --> log
cvkg-scene --> cvkg-spatial
Public API overview
Quadtree
| Method | Signature | Description |
|---|---|---|
new |
(bounds: Rect) -> Self |
Create a root node covering bounds. Default: 10 rects per leaf, max depth 5. |
insert |
(&mut self, rect: Rect) |
Insert a rect. Silently dropped if outside bounds. |
retrieve |
(&self, rect: Rect, out: &mut Vec<Rect>) |
Broad-phase query. Appends candidate rects to out. Callers must test exact overlap. |
No clear on Quadtree — drop and reconstruct to reset.
Bvh<T: Clone>
| Method | Signature | Description |
|---|---|---|
new |
() -> Self |
Create an empty BVH. |
insert |
(&mut self, rect: Rect, item: T) |
Stage an item with its bounding rect. Invalidates the tree. |
build |
(&mut self) |
Rebuild the BVH tree. Must be called after all insert and before any query. |
query |
(&self, rect: Rect) -> Vec<&T> |
Return references to items whose AABB overlaps rect. Empty if build not called. |
len |
(&self) -> usize |
Number of inserted items. |
is_empty |
(&self) -> bool |
true if no items inserted since last clear. |
clear |
(&mut self) |
Remove all items and discard the tree. |
Lifecycle: insert × N → build → query × N → clear.
SpatialHash<T: Clone>
| Method | Signature | Description |
|---|---|---|
new |
(cell_size: f32) -> Option<Self> |
Create with given cell size. Returns None if cell_size <= 0.0. |
insert |
(&mut self, rect: Rect, item: T) |
Register item in every cell rect overlaps. Item is cloned per cell. |
query |
(&self, rect: Rect) -> Vec<T> |
Return all items in cells overlapping rect. May contain duplicates. |
clear |
(&mut self) |
Remove all items. Does not free HashMap capacity. |
len |
(&self) -> usize |
Number of cell-item registrations (not unique items). |
is_empty |
(&self) -> bool |
true if no registrations since last clear. |
Re-exports
pub use ;
pub use Quadtree;
pub use SpatialHash;
BvhNode is re-exported for callers that need to inspect the tree structure directly.
Usage example
use ;
use Rect;
Use cases
- Scene picking (
cvkg-scene): query which graph nodes overlap a mouse cursor or selection rect usingBvh. - Broad-phase collision detection:
SpatialHashfor uniform-density object sets where per-frame rebuild is acceptable. - Dirty-rect merging:
Quadtreeto collect overlapping UI regions that need repaint. - Layout overlap checks: any crate that needs to know "what's in this region" without coupling to scene internals.
Edge cases and limitations
- BVH stale tree: calling
insertafterbuildinvalidates the tree.queryreturns empty untilbuildis called again. This is intentional — no silent rebuild. - BVH
T: Clonebound:build()rebuilds from theitemsvec without consuming it. Payloads must beClone. - Quadtree out-of-bounds: inserts outside
boundsare silently dropped. No error, no panic. - Quadtree no clear: there is no
clear()method. Drop theQuadtreeand reconstruct to reset. - Quadtree broad-phase only:
retrievereturns candidates from overlapping leaf nodes. Callers must perform exact AABB tests. - SpatialHash duplicates: items spanning multiple cells appear in
queryresults once per overlapping cell. Callers must deduplicate. - SpatialHash no removal: there is no per-item remove API. Call
clear()and re-insert. - SpatialHash
cell_size <= 0.0:newreturnsNone. - SpatialHash cell span limit: insert and query clamp cell span to 1000 cells per dimension to prevent CPU exhaustion from extreme coordinates.
- All structures use strict AABB overlap: touching edges (zero-width intersection) are not considered overlapping.
- No
unsafe: the entire crate is safe Rust.
Build flags / features / env vars
This crate has no feature flags, no environment variables, and no build-time configuration. Dependencies (cvkg-core, serde, log) are workspace-inherited and not optional.