roadgen
This is a road network generation tool based on Müller et al.. The basic idea is to extend LSystems to support intersection and snapping (selfsensitivity) and be guided by image maps (population density).
It features:
 road network generation/manipulation
 basic road network geometry construction
 basic building allotment distribution
Getting Started
 Add RoadNetwork to a game object in your scene an set generation parameters (e.g., street segment length)
 Add MockTerrain (or your own ITerrain implementation)
 [Optional] Add DummyAllotmentBuilder and RoadDensityMap. RoadDensityMap requires that you reference RoadNetwork.
 Add RoadDensityBasedSettlementSpawner (or your own settlement spawner implementation) and reference DummyAllotmentBuilder (or your own IAllotmentBuilder implementation) and RoadDensityMap
 Add RoadNetworkMesh and set materials (road segments and crossing), mesh detail (e.g., length step) and reference to RoadNetwork and terrain
Generation Parameters

Quadtree Params: The min. coordinates and size of the quatree (in world units) in which the road segments are put to optimize collision detections.

Quadtree Max Objects/Levels: Some other control parameters for the quadtree (max. number of items per quadrant and max. number of quadtree levels).

Segment Count Limit: Each road segment expands forward or spawns child road segments (branch) at each derivation step. This parameter controls the maximum amount of expansions a road segment can have.

Derivation Step Limit: Each derivation step is an opportunity for an existing road segments to expand or branch. This parameter controls the number of derivation steps.

Street/Highway Segment Length/Width: Road segments can be streets or highways. This parameter controls their width/length (in world units).

Street/Highway Branch Probability: This parameter is the normalized (01) probability of a road segment spawning another road segment.

Street/Highway Branch Population: TODO

Street Branch Time Delay: Number of derivation steps until the probability for streets to branch is evaluated.

Minimum Intersection = TODO

Snap Distance: Road segments “snap” to each other in order to form networklike structures. This is the maximum distance (in world units) that a road segment can have from another until it’s snapped.

Allotment Min/Max Half Diagonal: Building allotments are placed alongside road segments at a certain derivation interval. This is the min./max. diagonal size (in world units) of an allotment.

Allotment Min/Max Aspect: Once the diagonal size is sorted, the aspect length is sorted too. With the diagonal and aspect, we can define width and height. This controls the aspect (width / height) of the allotments.

Allotment Placement Loop: TODO

Settlement Spawn Delay: A settlement is a region where building allotments are placed. This parameter controls how many derivation steps needs to pass until a settlement can be randomly sorted.

Settlement Radius: This parameter controls the size of settlement from the point they started (in world units).

Settlement Crossing/Highway Probabilities: This parameter is the normalized (01) probability of a road segment that is either a highway or is in a crossing (i.e., has 2 orthogonal road segments connected to it) spawning a settlement.

Generate Highways/Streets: Enable/disable the generation of highways/streets.
Script Execution Order
(Pseudo)Randomness
Add GlobalSeeder to a game object in your scene to control pseudorandom number generation.
Advanced Usage
Road Network Generation
using System.Collections.Generic;
using RoadGen;
(...)
List<Segment> segments;
RoadGen.Quadtree quadtree;
RoadNetworkGenerator.DebugData debugData;
RoadNetworkGenerator.Generate(out segments, out quadtree, out debugData);
Road Network Traversal
Standard segment visitor
using System.Collections.Generic;
using RoadGen;
(...)
HashSet<Segment> visited = new HashSet<Segment>();
foreach (var segment in segments)
{
RoadNetworkTraversal.PreOrder(segment, (a) =>
{
// my visitation logic
return true;
},
mask,
ref visited);
}
Segment visitor w/ pertraversal parameter (Context)
using System.Collections.Generic;
using RoadGen;
(...)
struct MyContext
{
// my data
}
(...)
bool MyVisitor(Segment segment, ref MyContext myContext)
{
// my visitation logic
return true;
}
(...)
HashSet<Segment> visited = new HashSet<Segment>();
MyContext myContext;
foreach (var segment in roadNetwork.Segments)
{
RoadNetworkTraversal.PreOrder(segment,
ref myContext,
MyVisitor,
RoadNetworkTraversal.HIGHWAYS_MASK  RoadNetworkTraversal.STREETS_MASK,
ref visited);
}
Segment visitor w/ persegment parameter (User Data)
using System.Collections.Generic;
using RoadGen;
(...)
struct MyContext
{
// my context data
}
struct MyUserData
{
// my user data
}
(...)
bool MyVisitor(Segment segment, ref MyContext myContext, MyUserData i_myUserData, out MyUserData o_myUserData)
{
o_myUserData = new MyUserData();
// my visitation logic
return true;
}
(...)
HashSet<Segment> visited = new HashSet<Segment>();
MyContext myContext;
MyUserData myUserData;
foreach (var segment in roadNetwork.Segments)
{
RoadNetworkTraversal.PreOrder(segment,
ref myContext,
myUserData,
MyVisitor,
RoadNetworkTraversal.HIGHWAYS_MASK  RoadNetworkTraversal.STREETS_MASK,
ref visited);
}
Road Network Geometry Construction
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using RoadGen;
(...)
var geometry = RoadNetworkGeometryBuilder.Build(
scale,
Config.highwaySegmentWidth,
Config.streetSegmentWidth,
lengthStep,
segments,
RoadNetworkTraversal.HIGHWAYS_MASK  RoadNetworkTraversal.STREETS_MASK
);
List<Vector3> vertices = new List<Vector3>();
geometry.GetSegmentPositions().ForEach((p) =>
{
vertices.Add(new Vector3(p.x, heightmap.GetHeight(p.x, p.y), p.y));
});
geometry.GetCrossingPositions().ForEach((p) =>
{
vertices.Add(new Vector3(p.x, heightmap.GetHeight(p.x, p.y), p.y));
});
Mesh mesh = new Mesh();
mesh.vertices = vertices.ToArray();
mesh.triangles = geometry.GetCrossingIndices().ToArray();
mesh.uv = geometry.GetCrossingUvs().ToArray();
mesh.RecalculateNormals();
Custom Heightmap
Extend RoadGen.IHeightmap and implement:
float GetHeight(float x, float y);
bool Finished();
Custom Allotment Builder
Extend RoadGen.IAllotmentBuilder and implement:
GameObject Build(Allotment allotment, IHeightmap heightmap);