Skip to main content

Crate symbios_tensor

Crate symbios_tensor 

Source
Expand description

Tensor-field-driven procedural urban layout generator.

This crate generates realistic road networks and building lots on terrain defined by a symbios_ground::HeightMap. Roads follow the natural topography: major roads trace elevation contours while minor roads run along the gradient, producing organic street grids that adapt to hills and valleys. On flat terrain the field falls back to an axis-aligned Manhattan grid.

§Pipeline

  1. Road generationgenerate_roads seeds streamlines on a jittered grid and traces them through a TensorField using RK2 integration, snapping and splitting edges to form a planar RoadGraph.
  2. Graph rationalizationrationalize_graph rewrites the raw tracer output into clean geometry: RDP decimation removes unnecessary points, quadratic Bézier fillets smooth sharp bends, and elevation profiles are Laplacian-smoothed and grade-clamped. Arteries are traced through intersections for global straightening; severed side-streets are reconnected.
  3. Block extractionextract_blocks walks the planar graph with a minimum-angle (left-most turn) algorithm, producing closed CityBlock polygons for every bounded interior face.
  4. Lot subdivisionextract_lots recursively splits each block perpendicular to its longest edge (through the centroid) until pieces are below a configurable area threshold, then computes a street-aligned BuildingLot rectangle with front/side/rear setbacks.
  5. Terrain carvingcarve_roads and carve_lots flatten the heightmap under roads and building foundations with smooth embankment blending at the edges. Both accept a configurable blend_radius that controls how far the embankment zone extends — larger values produce wider, gentler slopes on steep terrain. carve_roads returns a boolean road-surface mask so that carve_lots can avoid overwriting already-flattened pavement. Road elevations use the rationalized (smoothed) node heights.
  6. Road pruningprune_unused_roads optionally removes roads that do not serve any building lot, keeping only the minimal connected sub-network via Dijkstra-based Steiner tree construction.
  7. 3D mesh generationgenerate_road_meshes produces engine-agnostic ProceduralMesh vertex buffers for intersection hubs (flat N-gon polygons with embankment skirts) and street ribbons (extruded strips with flanking skirt meshes).

§Quick start

use symbios_ground::HeightMap;
use symbios_tensor::*;

let heightmap = HeightMap::new(128, 128, 4.0);
let config = TensorConfig::default();

// 1. Generate road network
let mut graph = generate_roads(&heightmap, &config).expect("invalid config");

// 2. Rationalize: straighten, fillet, and smooth elevations
rationalize_graph(&mut graph, &heightmap, &RationalizeConfig::default());

// 3. Extract city blocks
extract_blocks(&mut graph);

// 4. Subdivide blocks into building lots
let mut hm = heightmap;
let lots = extract_lots(&graph, &mut hm, &LotConfig::default());

// 5. Carve roads and lots into terrain
let road_mask = carve_roads(&graph, &mut hm, &RoadMeshConfig::default(), 4.0);
carve_lots(&lots, &mut hm, 2.0, Some(&road_mask));

// 6. (Optional) Prune roads that don't serve any lot
prune_unused_roads(&mut graph, &lots);

// 7. Generate 3D road meshes
let meshes = generate_road_meshes(&graph, &hm, &RoadMeshConfig::default());
// meshes.hubs    — intersection polygons
// meshes.ribbons — street ribbon strips
// meshes.skirts  — embankment skirt meshes

Re-exports§

pub use carve::carve_lots;
pub use carve::carve_roads;
pub use graph::BlockId;
pub use graph::CityBlock;
pub use graph::EdgeId;
pub use graph::NodeId;
pub use graph::RoadEdge;
pub use graph::RoadGraph;
pub use graph::RoadNode;
pub use graph::RoadType;
pub use lots::BuildingLot;
pub use lots::LotConfig;
pub use lots::WaterPolicy;
pub use lots::extract_lots;
pub use polygons::block_centroid;
pub use polygons::extract_blocks;
pub use prune::prune_unused_roads;
pub use rationalize::RationalizeConfig;
pub use rationalize::rationalize_graph;
pub use rationalize::unify_road_types;
pub use roads_3d::ProceduralMesh;
pub use roads_3d::RoadMeshConfig;
pub use roads_3d::RoadMeshes;
pub use roads_3d::SkirtConfig;
pub use roads_3d::generate_road_meshes;
pub use streaming::CityStreamer;
pub use streaming::CityStreamerConfig;
pub use streaming::CityTile;
pub use tensor::TensorField;
pub use tensor::TensorFieldConfig;
pub use tracer::GenerationError;
pub use tracer::GenerationStage;
pub use tracer::TensorConfig;
pub use tracer::generate_roads;

Modules§

carve
Heightmap carving for roads and building lots.
geometry
Low-level 2D geometry primitives used by the tracer and spatial hash.
graph
Arena-based road graph with soft-deletion support for edge splitting.
lots
Building lot extraction from city blocks.
polygons
City block extraction from the planar road graph.
prune
Road pruning via Steiner tree construction.
rationalize
Graph rationalization: straighten and smooth the road network.
roads_3d
Engine-agnostic 3D road mesh generation.
spatial
Spatial hash grid for fast proximity and intersection queries during tracing.
streaming
On-demand tile-based city streaming for unbounded worlds.
tensor
Tensor field derived from heightmap surface normals.
topology
Shared topology helpers for the road graph.
tracer
Streamline tracer — the core road generation algorithm.