Skip to content

Procedural system

Jakub Lukasik edited this page Feb 23, 2023 · 13 revisions

Procedural system can be used for placing roads, runways or railways. It can be also used with mesh geometry for placing bridges, guard rails, walls, street lights and much more.

Glossary

Config: file storing whole setup for procedurals, located on path "defaults/way.cfg"

Profile: Main configuration unit, every waypoint in procedural sequence needs to address some profile (it has properties like style, type of construction and reference to textures used for generated terrain surface)

Profile style: defines lane, shoulder, border widths, features to use from feature set and much more. Profile can define up to 8 of styles that can be picked for each procedural waypoint individually

Feature set: with addition to profile, feature set defines setup used for placing geometry along placed procedural sequences

Profile style (or just "style")

Defines properties of road profile, in one profile can be setup multiple styles for fluent transition of minor changes on procedural waypoints between same profile types. Common use cases are temporary narrower parts of roads in towns, parts of road without footpaths or roads without nature strip. All properties are:

  • Lane width: paved road/lane width
  • Outer shoulder: outer shoulder width
  • Gutter: gutter width
  • Curb: curb width
  • Nature strip: nature strip width
  • Footpath: footpath width
  • Border: border material width, flat part of the embankment
  • Embankment: embankment width (horizontal width, single side)
  • Transition: width of transition from paved part to original underlaying terrain
  • Rise: min height above terrain
  • Turn radius: turn radius for sharp waypoint turns

Feature set

Configuration used for placement of defined mesh geometry along placed procedural sequences. Main idea is to define features and building blocks that can be referenced in profile style and then used to generate geometry from these blocks by number of lanes. Of course it is also possible to define one mesh for specific profile-style setup and use that, what helps with performance because less draw calls are needed. Consists of these properties:

  • Name: feature set name
  • Span: span between mesh instances
  • LOD size01: screen pixel size of object's bounding sphere at LOD0->1 transition
  • LOD size12: screen pixel size of object's bounding sphere at LOD1->2 transition
  • Surface offset: offset from object pivot to the surface (rail)
  • Lanes: list of lane feature definitions that can be referenced in profile style
  • Decors: list of decoration feature definitions that can be referenced in profile style
  • Blocks: list of blocks, used with lane feature, decorator feature and waypoint data to generate matching geometry
  • Matches: list of matches, used for specific match geometry, when we do not want to use automatic system

Feature set lane features ("lanes" in config)

list of possible features to select in profile style to be used for lane geometry. Consists of:

  • name: label to use for referencing from style
  • alias: single character used for search from match rule

Feature set decoration features ("decors" in config)

list of possible features to select in profile style to be used on the edge of the road. Consists of:

  • name: label to use for referencing from style
  • alias: single character used for search from match rule

Feature set blocks ("blocks" in config)

List of building blocks used for creation of temporary match item used for rendering along procedural spline. Properties:

  • name: label used for referencing from match item
  • alias: sequence of characters used for test with matching rule
  • left: sequence of paths to objdefs used when block is applied from left side of spline (in direction of spline)
  • center: sequence of paths to objdefs used when block is applied in center (mono paths or midlane in stereo paths)
  • right: sequence of paths to objdefs used when block is applied from right side of spline (in direction of spline)

Feature set match items ("matches" in config)

Matches are either automatically generated from blocks by lane and decor features and lane count defined on waypoint. But they can also be defined by user in which case user defined matches have higher priority.

  • match: rule to use when system is finding best fit for given waypoint
  • left: sequence of blocks to be used from left side of spline (in direction of spline)
  • center: sequence of blocks to be used in center of spline (in direction of spline)
  • right: sequence of blocks to be used from right side of spline (in direction of spline)

Match rule

When profile has valid connection to feature set, procedural system need to use correct meshes to render. There are multiple parameters used for making the decision of which of predefined meshes will be used. Most important is type of waypoint (mono/stereo) then lane count and lastly style of waypoint (style actually defines two properties that are used lane feature and decoration feature) Exact setup of these parameters for some feature set is called match and it is represented by character aliases. Every feature of feature set (either lane or decoration) is defined with single character alias. With this system every match can be represented as string of characters. For easier understanding there are few examples:

lane feature: L
decoration feature: d

matches:
	LLL    //mono road of three lanes without decorations
	dLd    //mono road of one lane with decorations on both sides
	L||L   //stereo road of one lane in every direction without decorations
	dLL||L //stereo road with two left lanes and decoration and one right lane without decoration

Lane geometry is necessary for correct rendering and there must be correct match (assembly of blocks) that covers whole carriage way. Decorations are always used as some extra geometry, that is not necessary for main part of lane geometry. There can be different decoration on left and on right side as there can be defined multiple features for one feature set. Decorations are usualy used for roadguards, lamp posts, fences or so.

Automatic match assembly system works as follows:

  1. system checks if left style reference some decoration and if so it tries to put it in left match's array (if feature isn't found in feature set or there isn't any block with feature's alias, system ignoes it and continue)
  2. approach is different for mono and stereo roads
    • for mono roads align property decides if left or right style is used for lane feature
      1. system tries to find block with alias of n-times of lane feature character (e.g. if lane feature alias is 'L', for 3 lane road it would search for "LLL")
      2. if previous search fails, system tries to find block with alias of one lane feature and use that bloks lane count times. If this steps also fails, creation of new match is aborted
    • for stereo road left and right lanes are handled separately
      1. system tries to find block with alias of n-times of left lane feature character (e.g. if lane feature alias is 'L', for 3 left lane road it would search for "LLL")
      2. if previous search fails, system tries to find block with alias of one left lane feature and use that bloks lane count times. If this steps also fails, creation of new match is aborted
      3. system tries to find block with alias of n-times of right lane feature character (e.g. if lane feature alias is 'L', for 3 right lane road it would search for "LLL")
      4. if previous search fails, system tries to find block with alias of one right lane feature and use that bloks lane count times. If this steps also fails, creation of new match is aborted
  3. system checks if right style reference some decoration and if so it tries to put it in right match's array (if feature isn't found in feature set or there isn't any block with feature's alias, system ignoes it and continue)

Additional objdef and block sequences formatting

After objdef or block string in sequence sufixes with multiple meaning can be used.

some_objdef_path@1.0 means, that mesh will be applied relative to previous in sequence and with 1 meter offset

some_objdef_path#1.0 means, that mesh will be applied absolute to begin of whole block and 1 meter from beginning

name_of_some_block^1.0 means, that block will be applied relative to lane

!some_objdef_path means, that mesh will be rotated in up axis

Example of simple feature set

{ name = "railway",
  span = 10.0,
  lanes = [
    { name = "track", alias = 'T' }
  ],
  decors = [
    { name = "with_guard", alias = 'g' }
  ],
  blocks = [
    { name = "track",
      alias = "T",
      left = ["rails/track_wood_01/track@0.0"],
      center = ["rails/track_wood_01/track@"],
      right = ["rails/track_wood_01/track@0.0"]
    },
    { name = "guard",
      alias = "g",
      left = ["guardrails/guardrails@0.15"],
      center = ["guardrails/guardrails@"],
      right = ["!guardrails/guardrails@0.05"]
    }
  ],
  matches = [
    { match = "gT||Tg", //manualy prepared match rule for stereo road with one lane and decoration in each way
      left = ["track@", "guard@"], //for left side rendering, guard and track block's left meshes will be used with relative offset from each other
      right = ["track@", "guard@"] //for right side rendering, guard and track block's right meshes will be used with relative offset from each other
    },
    { match = "gTTTg", //manualy prepared match rule for mono road with three lanes and decoration on each side
      left = ["guard@"], // left meshes of guard block will be rendered relatively to left end of center meshes
      center = ["track^", "track^", "track^"], //this part will be centered to spline, and center block meshes will be used
      right = ["guard@"] // right meshes of guard block will be rendered relatively to right end of center meshes
    }
  ]
}