Expand description
On-demand tile-based city streaming for unbounded worlds.
The full city pipeline (generate_roads → rationalize_graph →
extract_blocks → extract_lots) keeps the entire road graph in
memory, which is fine for fixed-size worlds but doesn’t scale to
10×10 km open-world regions. CityStreamer divides the world into
square tiles, runs the pipeline per tile on demand, caches the
results, and lets the caller evict distant tiles when memory grows.
§Per-tile coordinate system
Each tile is a square of side tile_size world units. Tile (i, j)
occupies world AABB [i·tile_size, (i+1)·tile_size] × [j·tile_size, (j+1)·tile_size]. The caller supplies a heightmap callback that
returns a HeightMap in tile-local coordinates (i.e. world
coordinates [0, tile_size] along each axis). The streamer offsets
the resulting graph nodes back into world space before returning.
§Seamlessness
Each tile is generated with an independent tensor field over its own
heightmap. The tensor field itself is locally consistent because it
samples the same global heightmap (assuming the caller’s callback is
consistent across tile boundaries), but streamlines do not extend
across tile borders — a road approaching the edge of tile (i, j)
ends there, and a separately-seeded road in tile (i+1, j) may or
may not align with it. Truly seamless cross-tile tracing is research
work and out of scope here. For most consumers this is acceptable
because tile borders are designed to fall on natural seams (rivers,
highway corridors) or are simply hidden by mesh LOD at distance.
Structs§
- City
Streamer - Streams city tiles on demand.
- City
Streamer Config - Configuration for a
CityStreamer. - City
Tile - One generated city tile: graph + lots + the heightmap that produced them. Node positions are in world coordinates (offset by the tile’s origin).