# BAI

From Mm2kiwi

## Introduction

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

## Format description

### Intersections

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

### Roads

The next section defines all the routes between the intersections.

### Culling

Lists the roads to compute ambients for depending on the given PSDL block id.

### Structure

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 PSDL blocks + 1 unsigned short **cull; // Pointers 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.