Implementation:CARLA simulator Carla MeshFactory
| Knowledge Sources | |
|---|---|
| Domains | Road Network, 3D Rendering, Mesh Generation |
| Last Updated | 2026-02-15 05:00 GMT |
Overview
MeshFactory generates 3D mesh geometry for roads, lanes, sidewalks, and safety walls from the OpenDRIVE road network data, supporting both standard and tessellated output with configurable resolution.
Description
The MeshFactory class (in carla::geom, implementation in MeshFactory.cpp, 1155 lines) is the primary mesh generation engine for CARLA's road visualization. It converts the abstract OpenDRIVE road descriptions into concrete 3D triangle meshes suitable for rendering.
Construction and Parameters: The factory is initialized with rpc::OpendriveGenerationParameters which control:
- resolution (vertex_distance) - Distance between vertices along the road in meters
- max_road_len (max_road_length) - Maximum chunk length for mesh splitting
- extra_lane_width (additional_width) - Extra width added to lanes
- wall_height - Height of safety walls at road edges
- vertex_width_resolution - Number of vertices across the lane width (for tessellation)
Core Generation Methods:
- Generate(const Road &road) - Iterates over all lane sections in a road and concatenates their meshes
- Generate(const LaneSection &lane_section) - Iterates over all lanes in a section and concatenates their meshes
- Generate(const Lane &lane, double s_start, double s_end) - The fundamental mesh generation method that creates a triangle strip from lane edge positions sampled at the configured resolution. Lane ID 0 (the center lane) produces no geometry. For straight lanes, an optimization adds vertices only at the start and end. Material is assigned as "sidewalk" or "road" based on the lane type.
- GenerateTesselated(const Lane &lane, ...) - Enhanced version that subdivides the lane width into multiple segments (controlled by vertex_width_resolution), producing a denser mesh with UV coordinates for texture mapping
Wall Generation:
- GenerateWalls() - Creates wall meshes for an entire lane section
- GenerateRightWall() / GenerateLeftWall() - Generate wall geometry along lane edges with configurable height, preventing vehicles from falling off road edges
Chunked Generation:
- GenerateWithMaxLen() - Splits road or lane section meshes into chunks of max_road_len meters, producing a vector of separate Mesh objects for efficient LOD and culling
- GenerateOrderedWithMaxLen() - Groups chunked meshes by Lane::LaneType in a map for type-specific rendering
Sidewalk Generation:
- GenerateSidewalk() - Produces elevated sidewalk meshes that include the side wall connecting the road surface to the sidewalk top surface
Lane Marking Generation:
- GenerateLaneMarkForRoad() - Generates lane line markers based on RoadInfoMarkRecord data, supporting different marking types (solid, broken, double) and computing the marking geometry as thin triangle strips along lane boundaries
Precision Constants:
- EPSILON = 10.0 * std::numeric_limits<double>::epsilon() - Standard precision offset
- MESH_EPSILON = 50.0 * std::numeric_limits<double>::epsilon() - Larger offset used for mesh-closing vertices
Usage
Use MeshFactory when generating the 3D visual representation of the road network. It is primarily used during map loading to produce the static road meshes for Unreal Engine rendering. The Map class invokes MeshFactory through its GenerateMesh() and GenerateChunkedMesh() methods. Configure the generation parameters via rpc::OpendriveGenerationParameters to control mesh density and quality.
Code Reference
Source Location
- Repository: CARLA
- File:
LibCarla/source/carla/road/MeshFactory.cpp - Lines: 1-1155
Signature
namespace carla {
namespace geom {
class MeshFactory {
public:
MeshFactory(rpc::OpendriveGenerationParameters params =
rpc::OpendriveGenerationParameters());
// Basic generation
std::unique_ptr<Mesh> Generate(const road::Road &road) const;
std::unique_ptr<Mesh> Generate(const road::LaneSection &lane_section) const;
std::unique_ptr<Mesh> Generate(const road::Lane &lane) const;
std::unique_ptr<Mesh> Generate(
const road::Lane &lane, const double s_start, const double s_end) const;
// Tessellated generation
std::unique_ptr<Mesh> GenerateTesselated(const road::Lane &lane) const;
std::unique_ptr<Mesh> GenerateTesselated(
const road::Lane &lane, const double s_start, const double s_end) const;
// Ordered generation
void GenerateLaneSectionOrdered(
const road::LaneSection &lane_section,
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<Mesh>>> &result) const;
// Sidewalks
std::unique_ptr<Mesh> GenerateSidewalk(const road::LaneSection &lane_section) const;
std::unique_ptr<Mesh> GenerateSidewalk(const road::Lane &lane) const;
std::unique_ptr<Mesh> GenerateSidewalk(
const road::Lane &lane, const double s_start, const double s_end) const;
// Walls
std::unique_ptr<Mesh> GenerateWalls(const road::LaneSection &lane_section) const;
std::unique_ptr<Mesh> GenerateRightWall(
const road::Lane &lane, const double s_start, const double s_end) const;
std::unique_ptr<Mesh> GenerateLeftWall(
const road::Lane &lane, const double s_start, const double s_end) const;
// Chunked generation
std::vector<std::unique_ptr<Mesh>> GenerateWithMaxLen(const road::Road &road) const;
std::vector<std::unique_ptr<Mesh>> GenerateWallsWithMaxLen(const road::Road &road) const;
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<Mesh>>>
GenerateOrderedWithMaxLen(const road::Road &road) const;
// Lane markings
std::vector<std::unique_ptr<Mesh>> GenerateLaneMarkForRoad(const road::Road &road) const;
struct RoadParameters {
float resolution = 2.0f;
float max_road_len = 50.0f;
float extra_lane_width = 0.0f;
float wall_height = 0.6f;
float vertex_width_resolution = 4.0f;
} road_param;
};
} // namespace geom
} // namespace carla
Import
#include "carla/road/MeshFactory.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| params | rpc::OpendriveGenerationParameters |
No | Generation parameters controlling vertex distance, max road length, additional width, wall height, and width resolution |
| road | const road::Road & |
Yes | Road segment to generate mesh for |
| lane_section | const road::LaneSection & |
Yes | Lane section to generate mesh for |
| lane | const road::Lane & |
Yes | Individual lane to generate mesh for |
| s_start / s_end | double |
No | Start and end s-coordinates to limit mesh generation range |
Outputs
| Name | Type | Description |
|---|---|---|
| Mesh | std::unique_ptr<Mesh> |
Single mesh containing triangle geometry with materials |
| Mesh list | std::vector<std::unique_ptr<Mesh>> |
Chunked meshes split by maximum length |
| Ordered meshes | std::map<Lane::LaneType, std::vector<std::unique_ptr<Mesh>>> |
Meshes grouped by lane type for selective rendering |
Usage Examples
Generating a Road Mesh
#include "carla/road/MeshFactory.h"
// Create factory with custom parameters
carla::rpc::OpendriveGenerationParameters params;
params.vertex_distance = 1.0;
params.max_road_length = 100.0;
params.wall_height = 0.8;
carla::geom::MeshFactory factory(params);
// Generate mesh for a single road
auto mesh = factory.Generate(road);
// Access vertices and triangles
const auto &vertices = mesh->GetVertices();
const auto &indexes = mesh->GetIndexes();
Generating Chunked Meshes for Rendering
// Split road into chunks for efficient rendering
auto chunks = factory.GenerateWithMaxLen(road);
for (auto &chunk : chunks) {
// Each chunk is <= max_road_len meters long
UploadToGPU(std::move(chunk));
}
Generating Walls and Sidewalks
// Generate safety walls for a lane section
auto walls = factory.GenerateWalls(lane_section);
// Generate sidewalk geometry with side walls
auto sidewalk = factory.GenerateSidewalk(lane_section);