From Mm2kiwi
Revision as of 20:52, 25 May 2006 by Fre-Ber (talk | contribs) (Culling: Description of the function of the lists)

Jump to: navigation, search


Each city may have one BAI-file. This file defines paths for controlling ambients such as pedestrians and automated traffic.

Format description


A BAI-file is built up in three sections. The first section defines intersections.


The next section defines all the routes between the intersections.


Lists the roads to compute ambients for depending on the given PSDL block id. This section is divided into two parts, one for large AI-bubbles and one for small. Each part gives one list of road indices that are to be active for each block of the PSDL. Active means that AI computations are performed for the roads listed for the block that the player is currently on. The first list in each part should be ignored and thus set to a length of zero.


In a pseudo-C style structure, a BAI-file looks like this:

struct BAI
    char[4]         header = "CAI1";
    unsigned short  nIntersections;                 // Number of intersections
    unsigned short  nRoads;                         // Number of roads
    Road            roads[nRoads];                  // Roads
    Intersection    intersections[nIntersections];  // Intersections
    Culling         culling;                        // AI culling ("bubbles")
struct Road
    unsigned short id;
    unsigned short nSections;       // Number of vertex sets
    unsigned short unknown0;        // No idea
    unsigned short nBlocks;         // Number of block references
    unsigned short blocks[nBlocks]; // References to the PSDL
    float          unknown1;        // Not sure. Speed threshold?
    float          unknown2;        // Always == 15

    RoadData       right;           // Data for right side
    RoadData       left;            // Data for left side

    float  distance[nSections];     // Distances between centre points of the road
    Vertex origin[nSections];       // Coordsys for tangent, origin
    Vector xOrientation[nSections]; // Coordsys for tangent, X axis
    Vector yOrientation[nSections]; // Coordsys for tangent, Y axis
    Vector zOrientation[nSections]; // Coordsys for tangent, Z axis
    Vector tangent[nSections];      // Direction of the road at each cross-section

    RoadEnd        end;             // End of the road
    RoadEnd        start;           // Start of the road
struct Intersection
    unsigned short id;
    unsigned short block;         // Reference to the PSDL, (index + 1)
    Vertex         center;        // Center point of intersection
    unsigned short nRoads;        // Number of connected roads
    unsigned long  roads[nRoads]; // Clockwise ordered references to roads connected to this intersection
struct Culling
    unsigned long    nBlocks;   // Number of blocks in the PSDL + 1
    CullingList      cull0[nBlocks];
    CullingList      cull1[nBlocks];
struct CullList
    unsigned short nRoads;
    unsigned short roads[nRoads];  // references to roads?
struct RoadData
    unsigned short nLanes;        // Number of lanes
    unsigned short nTrams;        // Number of tram rails (bool?)
    unsigned short nTrains;       // Number of train rails (bool?)
    unsigned short unknown3;      // Sidewalk? Always == 1 (bool?)
    unsigned short unknown4;      // Road type? 0, 1, 2 or 3

    float  lanesDistances[nLanes][nSections]; // Distances for right lanes
    float  distance[nSections];               // Outer edge distance
    float  Unknown[11 + nLanes];              // Something about the lanes, gladly padded with 0xcdcdcdcd
    Vertex lLanesVertices[nLanes][nSections]; // Vertices for driving lane splines
    Vertex sidewalkCenter[nSections];         // Vertices for sidewalk central spline
    Vertex tramVertices[nTrams][nSections];   // Vertices for tram rail splines
    Vertex trainVertices[nTrains][nSections]; // Vertices for train rail splines
    Vertex sidewalkInner[nSections];          // Vertices for sidewalk inner spline
    Vertex sidewalkOuter[nSections];          // Vertices for sidewalk outer spline
struct RoadEnd
    unsigned long  intersectionID;        // Reference to Intersection[].id
    unsigned short unknown0;              // Always 0xcdcd
    unsigned long  vehicleRule;           // See below
    unsigned long  intersectionRoadIndex; // Index in the intersections road list or 0xcdcdcdcd
    Vertex trafficLightOrigin;            // Origin of traffic light
    Vertex trafficLightAxis;              // Orientation of traffic light
struct Vertex
    float x;
    float y;
    float z;
struct Vector
    float x;
    float y;
    float z;

Values for RoadEnd.vehicleRule:

  • 0 - Stop sign. The vehicles will stop, longest waiting vehicle drives first.
  • 1 - Traffic light. One road at a time. All roads connected to the same intersection must have this control type, if not, the vehicles will behave as if it was a stop sign and the traffic light will blink between green and yellow. Traffic lights will only show up if their coordinates are not (0, 0, 0).
  • 2 - Always stop. The vehicles stop and never proceed.
  • 3 - Never stop. The vehicles will drive straight through the intersection without even slowing down.