plozone
High-precision 3D spatial zone management for Rust.
Geofencing, octree hole-scanning, adaptive density partitioning, and realtime
multiplayer zone sync — in one crate. Sub-microsecond zone queries, 0-RTT QUIC
transport, lock-free position updates, and an no_std embedded story.
Why
Every spatial project reinvents the same primitives: is this point inside a zone?, did the entity enter or leave?, is this region fully scanned?. Plozone is the single library that answers these questions across domains — real-world geospatial, game maps, robotics, autonomous vehicles, and IoT — with one consistent API.
| Plozone | OctoMap | Tile38 | rstar | |
|---|---|---|---|---|
| 3D zone shapes | full | voxel only | 2D polygons | AABB only |
| Hole scanning | octree-based | yes | no | no |
| Dynamic zones (runtime) | yes | no | partial | no |
| Realtime sync (WS + QUIC + io_uring) | yes | no | WS only | no |
| Game / arbitrary coords | yes | no | no | no |
| AV stack (EKF, V2X, HD map) | yes | no | no | no |
| no_std embedded | yes | no | no | partial |
| Voxel pathfinding | A* | no | no | no |
| Rust-native | yes | C++ bindings | Go server | yes |
Quick start
[]
= { = "0.1", = ["full"] }
use ;
let conv = new; // WGS84 origin
let store = from_entries;
// Point-in-zone query: geodetic in, matching zone IDs out.
let hits = store.query_geodetic;
assert_eq!;
// Scan for unsampled volume against an octree point cloud.
let octree = new;
let result = run_scan;
println!;
Architecture
Input: RTK GNSS / game coords / sensor XYZ + Timestamp
│
▼
┌──────────────────────────────────────────────┐
│ ZoneStore │
│ ┌─────────────┐ ┌───────────────────────┐ │
│ │ enum Zone │ │ trait ZoneShape │ │
│ │ (wire-safe) │ │ (custom / dynamic) │ │
│ └──────┬──────┘ └──────────┬────────────┘ │
│ └──────────┬──────────┘ │
│ Box<dyn ZoneShape> + R-tree (ENU) │
│ Priority + Layer support │
└─────────────────────┬────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Point-in-Zone Hole Scanner Density Query
(< 1 µs) (octree scan) (coarse/fine)
Two-layer zone design:
enum Zone— built-in shapes (sphere, cylinder, box, polygon, frustum, convex hull, union, shrinking). FullySerialize/Deserialize, wire-safe.trait ZoneShape— implement for any custom geometry (dynamic radius, entity-following, closure-based).Zoneimplements it automatically.ZoneStoreholdsBox<dyn ZoneShape>internally — mix both freely.
Features
| Feature | What it provides |
|---|---|
| (default) | coord, zone, octree, store, scan — zero-dep core |
parallel |
Rayon-accelerated scanning |
pathfinding |
3D voxel A* over octree (find_path, PathNode) |
tiled |
Global-scale multi-origin world (TiledWorld, TileKey) |
game |
Game-map coord systems + containers (GameWorld, LayeredMap, ChunkedGameWorld, PortalSystem) |
net |
Wire codec: encode/decode, ClientMsg/ServerMsg, PosTracker with dead-reckoning |
pipeline |
Realtime ingestion pipeline with crossbeam channels |
server |
WebSocket zone server + client (ZoneServer, ShardedZoneServer, ZoneClient, AtomicPos) |
quic |
QUIC transport via quinn — 0-RTT reconnect, datagram broadcast, cellular handoff survival |
io_uring |
Linux io_uring transport via tokio-uring — ~30% lower latency than epoll |
av |
Autonomous vehicle: EKF fusion, sensor FOV zones, safety envelope, HD map, behaviour zones, V2X |
bevy |
Bevy ECS plugin (Spatial3dPlugin, ZoneTracker, events) |
embedded |
no_std-compatible linear-scan store (ZoneStoreEmbed) |
lidar |
Pose/quaternion math + scan ingestion (Pose, Quat, ScanFrame, ingest_scan) |
terrain |
Marching cubes mesh extraction, OBJ/PLY export, density export |
gnss |
RTK GNSS ingestion stubs (u-blox, NTRIP) |
# Everything:
= { = "0.1", = ["full"] }
# Or pick what you need:
= { = "0.1", = ["server", "quic"] }
Module map
plozone
├── coord WGS84 ↔ ENU conversion, CoordSystem trait
├── zone ZoneShape trait, Zone enum, custom shapes, priority/layer
├── store ZoneStore (R-tree indexed), ZoneDiff, layer queries
├── octree OctreeNode, adaptive subdivision, depth_for_accuracy
├── scan Hole scanner, ScanMode, ScanResult, multiscale
├── net* Wire codec, ClientMsg/ServerMsg, PosTracker (dead reckoning)
├── pipeline* Realtime ingestion loop (crossbeam)
├── server* WebSocket ZoneServer, ShardedZoneServer, AtomicPos, hysteresis
├── client* ZoneClient with adaptive rate + snapshot sync
├── quic* QUIC transport (quinn + rustls, datagram broadcast)
├── av* ImuFusion, sensor FOV, SafetyEnvelope, HdMap, V2X
├── bevy* Bevy ECS plugin
├── embedded* ZoneStoreEmbed (no_std, no allocator required)
├── pathfinding* Voxel A* over octree
├── tiled* TiledWorld (global-scale, multi-origin)
├── game* Game coord systems + world containers
├── lidar* Pose + quaternion math, scan ingestion
├── terrain* Marching cubes, OBJ/PLY export, density export
└── gnss* RTK GNSS stubs (u-blox, NTRIP)
*feature-gated
Performance
| Operation | Time |
|---|---|
| Zone query (1k zones, R-tree) | ~730 ns |
| Octree batch insert 1k pts | ~435 µs |
| Hole scan depth 4 | ~12 µs |
| Coord WGS84→ENU | ~128 ns |
| Coord ENU→WGS84 | ~655 ns |
Benchmarks via cargo bench --features full (criterion).
Transports
| Transport | Feature | Latency | Use case |
|---|---|---|---|
| WebSocket | server |
~5 ms p99 | Browser clients, general purpose |
| QUIC | quic |
~2 ms p99 | Mobile (cellular handoff), 0-RTT reconnect |
| io_uring | io_uring |
< 1 ms p99 | Linux server, maximum throughput |
All transports share the same postcard-encoded wire format and ZoneServer
core — swap transports without changing business logic.
Scale
| Tier | Entities | Zones | Latency p99 | Infra |
|---|---|---|---|---|
| Single process, tokio | ~5k | ~100k | < 5 ms | 1 server |
| Sharded (16), tokio | ~80k | ~100k | < 2 ms | 1 server |
| Sharded (64), io_uring | ~300k | ~500k | < 1 ms | 1 server |
| Multi-process cluster | ~5M+ | unlimited | < 5 ms | Load balancer + N servers |
Building and testing
Project stats
- ~6,100 lines of Rust
- 103 unit tests, 1 integration test, 2 doctests
- 0 clippy warnings
cargo publish --dry-runclean- Edition 2024
License
MIT. See LICENSE.
Contributing
See CONTRIBUTING.md.
Design document
Full architecture and rationale: PLOZONE.md (3,700+ lines).