# 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.
[](https://crates.io/crates/plozone)
[](LICENSE)
[](#building-and-testing)
---
## 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.
| 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
```toml
[dependencies]
plozone = { version = "0.1", features = ["full"] }
```
```rust
use plozone::{
coord::EnuConverter, octree::OctreeNode, store::ZoneStore,
zone::{Zone, ZoneEntry}, scan::{run_scan, ScanMode},
};
let conv = EnuConverter::new(10.7626, 106.6601, 0.0); // WGS84 origin
let store = ZoneStore::from_entries(&[
ZoneEntry::new(1, Zone::Cylinder {
center: [10.7626, 106.6601], radius_m: 50.0,
z_min: 0.0, z_max: 20.0,
}),
], &conv);
// Point-in-zone query: geodetic in, matching zone IDs out.
let hits = store.query_geodetic(10.7626, 106.6601, 5.0, &conv);
assert_eq!(hits, vec![1]);
// Scan for unsampled volume against an octree point cloud.
let octree = OctreeNode::new([0.0; 3], 64.0);
let result = run_scan(&octree, &store, 1, &ScanMode::Coarse { depth: 4 });
println!("coverage: {:.1}%", result.coverage_pct);
```
## 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). Fully `Serialize`/`Deserialize`, wire-safe.
- **`trait ZoneShape`** — implement for any custom geometry (dynamic radius,
entity-following, closure-based). `Zone` implements it automatically.
- `ZoneStore` holds `Box<dyn ZoneShape>` internally — mix both freely.
## Features
| *(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) |
```toml
# Everything:
plozone = { version = "0.1", features = ["full"] }
# Or pick what you need:
plozone = { version = "0.1", features = ["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
| 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
| 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
| 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
```sh
cargo build # core only (no deps)
cargo test --features full # all 103 tests
cargo test --features quic # QUIC transport tests
cargo test --features io_uring # io_uring tests (Linux)
cargo bench --features full # criterion benchmarks
cargo clippy --features full -- -D warnings # lint
```
## Project stats
- ~6,100 lines of Rust
- 103 unit tests, 1 integration test, 2 doctests
- 0 clippy warnings
- `cargo publish --dry-run` clean
- Edition 2024
## License
MIT. See [LICENSE](LICENSE).
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
## Design document
Full architecture and rationale: [PLOZONE.md](PLOZONE.md) (3,700+ lines).