31 static constexpr
double EPSILON = 10.0 * std::numeric_limits<double>::epsilon();
32 static constexpr
double MESH_EPSILON = 50.0 * std::numeric_limits<double>::epsilon();
39 return std::make_unique<Mesh>(out_mesh);
44 for (
auto &&lane_pair : lane_section.
GetLanes()) {
45 out_mesh += *
Generate(lane_pair.second);
47 return std::make_unique<Mesh>(out_mesh);
53 return Generate(lane, s_start, s_end);
63 const road::Lane &lane,
const double s_start,
const double s_end)
const {
71 if (lane.
GetId() == 0) {
72 return std::make_unique<Mesh>(out_mesh);
74 double s_current = s_start;
76 std::vector<geom::Vector3D> vertices;
81 vertices.push_back(edges.first);
82 vertices.push_back(edges.second);
88 vertices.push_back(edges.first);
89 vertices.push_back(edges.second);
93 }
while(s_current < s_end);
100 vertices.push_back(edges.first);
101 vertices.push_back(edges.second);
109 return std::make_unique<Mesh>(out_mesh);
113 const road::Lane& lane,
const double s_start,
const double s_end)
const {
121 if (lane.
GetId() == 0) {
122 return std::make_unique<Mesh>(out_mesh);
124 double s_current = s_start;
126 std::vector<geom::Vector3D> vertices;
129 const int segments_number = vertices_in_width - 1;
131 std::vector<geom::Vector2D> uvs;
138 const geom::Vector3D segments_size = ( edges.second - edges.first ) / segments_number;
141 for (
int i = 0; i < vertices_in_width; ++i) {
143 vertices.push_back(current_vertex);
144 current_vertex = current_vertex + segments_size;
150 }
while (s_current < s_end);
156 std::pair<carla::geom::Vector3D, carla::geom::Vector3D> edges =
158 const geom::Vector3D segments_size = (edges.second - edges.first) / segments_number;
161 for (
int i = 0; i < vertices_in_width; ++i)
164 vertices.push_back(current_vertex);
165 current_vertex = current_vertex + segments_size;
176 const size_t number_of_rows = (vertices.size() / vertices_in_width);
178 for (
size_t i = 0; i < (number_of_rows - 1); ++i) {
179 for (
size_t j = 0; j < vertices_in_width - 1; ++j) {
180 out_mesh.
AddIndex( j + ( i * vertices_in_width ) + 1);
181 out_mesh.
AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1);
182 out_mesh.
AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1);
184 out_mesh.
AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1);
185 out_mesh.
AddIndex( ( j + 1 ) + ( ( i + 1 ) * vertices_in_width ) + 1);
186 out_mesh.
AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1);
190 return std::make_unique<Mesh>(out_mesh);
199 std::vector<size_t> redirections;
200 for (
auto &&lane_pair : lane_section.
GetLanes()) {
201 auto it = std::find(redirections.begin(), redirections.end(), lane_pair.first);
202 if ( it == redirections.end() ) {
203 redirections.push_back(lane_pair.first);
204 it = std::find(redirections.begin(), redirections.end(), lane_pair.first);
206 size_t PosToAdd = it - redirections.begin();
215 if( result[lane_pair.second.GetType()].size() <= PosToAdd ){
216 result[lane_pair.second.GetType()].push_back(std::make_unique<Mesh>(out_mesh));
218 uint32_t verticesinwidth = 0;
220 verticesinwidth = vertices_in_width;
226 (result[lane_pair.second.GetType()][PosToAdd])->ConcatMesh(out_mesh, verticesinwidth);
234 for (
auto &&lane_pair : lane_section.
GetLanes()) {
235 const double s_start = lane_pair.second.GetDistance() +
EPSILON;
236 const double s_end = lane_pair.second.GetDistance() + lane_pair.second.GetLength() -
EPSILON;
239 return std::make_unique<Mesh>(out_mesh);
248 const double s_end )
const {
257 if (lane.
GetId() == 0) {
258 return std::make_unique<Mesh>(out_mesh);
260 double s_current = s_start;
262 std::vector<geom::Vector3D> vertices;
264 const int vertices_in_width = 6;
265 const int segments_number = vertices_in_width - 1;
266 std::vector<geom::Vector2D> uvs;
272 std::pair<geom::Vector3D, geom::Vector3D> edges =
277 vertices.push_back(low_vertex_first);
280 vertices.push_back(edges.first);
283 vertices.push_back(edges.first);
286 vertices.push_back(edges.second);
289 vertices.push_back(edges.second);
292 vertices.push_back(low_vertex_second);
298 }
while (s_current < s_end);
304 std::pair<carla::geom::Vector3D, carla::geom::Vector3D> edges =
310 vertices.push_back(low_vertex_first);
313 vertices.push_back(edges.first);
316 vertices.push_back(edges.first);
319 vertices.push_back(edges.second);
322 vertices.push_back(edges.second);
325 vertices.push_back(low_vertex_second);
336 const int number_of_rows = (vertices.size() / vertices_in_width);
338 for (
size_t i = 0; i < (number_of_rows - 1); ++i) {
339 for (
size_t j = 0; j < vertices_in_width - 1; ++j) {
341 if(j == 1 || j == 3){
345 out_mesh.
AddIndex( j + ( i * vertices_in_width ) + 1);
346 out_mesh.
AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1);
347 out_mesh.
AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1);
349 out_mesh.
AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1);
350 out_mesh.
AddIndex( ( j + 1 ) + ( ( i + 1 ) * vertices_in_width ) + 1);
351 out_mesh.
AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1);
356 return std::make_unique<Mesh>(out_mesh);
361 const auto min_lane = lane_section.
GetLanes().begin()->first == 0 ?
362 1 : lane_section.
GetLanes().begin()->first;
363 const auto max_lane = lane_section.
GetLanes().rbegin()->first == 0 ?
364 -1 : lane_section.
GetLanes().rbegin()->first;
366 for (
auto &&lane_pair : lane_section.
GetLanes()) {
367 const auto &lane = lane_pair.second;
368 const double s_start = lane.GetDistance() +
EPSILON;
369 const double s_end = lane.GetDistance() + lane.GetLength() -
EPSILON;
370 if (lane.GetId() == max_lane) {
373 if (lane.GetId() == min_lane) {
377 return std::make_unique<Mesh>(out_mesh);
381 const road::Lane &lane,
const double s_start,
const double s_end)
const {
389 if (lane.
GetId() == 0) {
390 return std::make_unique<Mesh>(out_mesh);
392 double s_current = s_start;
395 std::vector<geom::Vector3D> r_vertices;
400 r_vertices.push_back(edges.first + height_vector);
401 r_vertices.push_back(edges.first);
407 r_vertices.push_back(edges.first + height_vector);
408 r_vertices.push_back(edges.first);
412 }
while(s_current < s_end);
419 r_vertices.push_back(edges.first + height_vector);
420 r_vertices.push_back(edges.first);
428 return std::make_unique<Mesh>(out_mesh);
432 const road::Lane &lane,
const double s_start,
const double s_end)
const {
440 if (lane.
GetId() == 0) {
441 return std::make_unique<Mesh>(out_mesh);
443 double s_current = s_start;
446 std::vector<geom::Vector3D> l_vertices;
451 l_vertices.push_back(edges.second);
452 l_vertices.push_back(edges.second + height_vector);
458 l_vertices.push_back(edges.second);
459 l_vertices.push_back(edges.second + height_vector);
463 }
while(s_current < s_end);
470 l_vertices.push_back(edges.second);
471 l_vertices.push_back(edges.second + height_vector);
479 return std::make_unique<Mesh>(out_mesh);
484 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list;
487 mesh_uptr_list.insert(
488 mesh_uptr_list.end(),
489 std::make_move_iterator(section_uptr_list.begin()),
490 std::make_move_iterator(section_uptr_list.end()));
492 return mesh_uptr_list;
497 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list;
499 mesh_uptr_list.emplace_back(
Generate(lane_section));
505 Mesh lane_section_mesh;
506 for (
auto &&lane_pair : lane_section.
GetLanes()) {
507 lane_section_mesh += *
Generate(lane_pair.second, s_current, s_until);
509 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh));
512 if (s_end - s_current > EPSILON) {
513 Mesh lane_section_mesh;
514 for (
auto &&lane_pair : lane_section.
GetLanes()) {
515 lane_section_mesh += *
Generate(lane_pair.second, s_current, s_end);
517 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh));
520 return mesh_uptr_list;
525 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> mesh_uptr_list;
527 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> section_uptr_list =
GenerateOrderedWithMaxLen(lane_section);
528 mesh_uptr_list.insert(
529 std::make_move_iterator(section_uptr_list.begin()),
530 std::make_move_iterator(section_uptr_list.end()));
532 return mesh_uptr_list;
538 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> mesh_uptr_list;
545 std::vector<size_t> redirections;
549 for (
auto &&lane_pair : lane_section.
GetLanes()) {
550 Mesh lane_section_mesh;
554 lane_section_mesh += *
GenerateSidewalk(lane_pair.second, s_current, s_until);
557 auto it = std::find(redirections.begin(), redirections.end(), lane_pair.first);
558 if (it == redirections.end()) {
559 redirections.push_back(lane_pair.first);
560 it = std::find(redirections.begin(), redirections.end(), lane_pair.first);
563 size_t PosToAdd = it - redirections.begin();
564 if (mesh_uptr_list[lane_pair.second.GetType()].size() <= PosToAdd) {
565 mesh_uptr_list[lane_pair.second.GetType()].push_back(std::make_unique<Mesh>(lane_section_mesh));
567 uint32_t verticesinwidth = 0;
569 verticesinwidth = vertices_in_width;
575 (mesh_uptr_list[lane_pair.second.GetType()][PosToAdd])->ConcatMesh(lane_section_mesh, verticesinwidth);
580 if (s_end - s_current > EPSILON) {
581 for (
auto &&lane_pair : lane_section.
GetLanes()) {
582 Mesh lane_section_mesh;
589 auto it = std::find(redirections.begin(), redirections.end(), lane_pair.first);
590 if (it == redirections.end()) {
591 redirections.push_back(lane_pair.first);
592 it = std::find(redirections.begin(), redirections.end(), lane_pair.first);
595 size_t PosToAdd = it - redirections.begin();
597 if (mesh_uptr_list[lane_pair.second.GetType()].size() <= PosToAdd) {
598 mesh_uptr_list[lane_pair.second.GetType()].push_back(std::make_unique<Mesh>(lane_section_mesh));
600 uint32_t verticesinwidth = 0;
602 verticesinwidth = vertices_in_width;
608 *(mesh_uptr_list[lane_pair.second.GetType()][PosToAdd]) += lane_section_mesh;
613 return mesh_uptr_list;
618 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list;
621 mesh_uptr_list.insert(
622 mesh_uptr_list.end(),
623 std::make_move_iterator(section_uptr_list.begin()),
624 std::make_move_iterator(section_uptr_list.end()));
626 return mesh_uptr_list;
631 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list;
633 const auto min_lane = lane_section.
GetLanes().begin()->first == 0 ?
634 1 : lane_section.
GetLanes().begin()->first;
635 const auto max_lane = lane_section.
GetLanes().rbegin()->first == 0 ?
636 -1 : lane_section.
GetLanes().rbegin()->first;
645 Mesh lane_section_mesh;
646 for (
auto &&lane_pair : lane_section.
GetLanes()) {
647 const auto &lane = lane_pair.second;
648 if (lane.GetId() == max_lane) {
651 if (lane.GetId() == min_lane) {
655 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh));
658 if (s_end - s_current > EPSILON) {
659 Mesh lane_section_mesh;
660 for (
auto &&lane_pair : lane_section.
GetLanes()) {
661 const auto &lane = lane_pair.second;
662 if (lane.GetId() == max_lane) {
665 if (lane.GetId() == min_lane) {
669 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh));
672 return mesh_uptr_list;
677 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list;
681 mesh_uptr_list.insert(
682 mesh_uptr_list.end(),
683 std::make_move_iterator(roads.begin()),
684 std::make_move_iterator(roads.end()));
690 if (roads.size() == walls.size()) {
691 for (
size_t i = 0; i < walls.size(); ++i) {
692 *mesh_uptr_list[i] += *walls[i];
695 mesh_uptr_list.insert(
696 mesh_uptr_list.end(),
697 std::make_move_iterator(walls.begin()),
698 std::make_move_iterator(walls.end()));
702 return mesh_uptr_list;
712 for (
auto &pair_map : result)
714 std::vector<std::unique_ptr<Mesh>>& origin = roads[pair_map.first];
715 std::vector<std::unique_ptr<Mesh>>& source = pair_map.second;
716 std::move(source.begin(), source.end(), std::back_inserter(origin));
722 std::vector<std::unique_ptr<Mesh>>& inout,
723 std::vector<std::string>& outinfo )
const 726 for (
auto&& lane : lane_section.GetLanes()) {
727 if (lane.first != 0) {
730 outinfo.push_back(
"white");
735 outinfo.push_back(
"yellow");
745 std::vector<std::unique_ptr<Mesh>>& inout,
746 std::vector<std::string>& outinfo )
const {
750 double s_current = s_start;
751 std::vector<geom::Vector3D> vertices;
752 std::vector<size_t> indices;
757 if (road_info_mark !=
nullptr) {
760 switch (lane_mark_info.
type) {
762 size_t currentIndex = out_mesh.
GetVertices().size() + 1;
764 std::pair<geom::Vector3D, geom::Vector3D> edges = lane.
GetCornerPositions(s_current, 0);
767 director /= director.
Length();
774 out_mesh.
AddIndex(currentIndex + 1);
775 out_mesh.
AddIndex(currentIndex + 2);
777 out_mesh.
AddIndex(currentIndex + 1);
778 out_mesh.
AddIndex(currentIndex + 3);
779 out_mesh.
AddIndex(currentIndex + 2);
785 size_t currentIndex = out_mesh.
GetVertices().size() + 1;
787 std::pair<geom::Vector3D, geom::Vector3D> edges =
791 director /= director.
Length();
798 if (s_current > s_end)
804 director = edges.second - edges.first;
805 director /= director.
Length();
806 endmarking = edges.first + director * lane_mark_info.
width;
812 out_mesh.
AddIndex(currentIndex + 1);
813 out_mesh.
AddIndex(currentIndex + 2);
815 out_mesh.
AddIndex(currentIndex + 1);
816 out_mesh.
AddIndex(currentIndex + 3);
817 out_mesh.
AddIndex(currentIndex + 2);
861 }
while (s_current < s_end);
865 if (road_info_mark !=
nullptr) {
869 director /= director.
Length();
875 inout.push_back(std::make_unique<Mesh>(out_mesh));
883 std::vector<std::unique_ptr<Mesh>>& inout,
884 std::vector<std::string>& outinfo )
const 889 double s_current = s_start;
890 std::vector<geom::Vector3D> vertices;
891 std::vector<size_t> indices;
896 if (road_info_mark !=
nullptr) {
899 switch (lane_mark_info.
type) {
901 size_t currentIndex = out_mesh.
GetVertices().size() + 1;
917 out_mesh.
AddIndex(currentIndex + 1);
918 out_mesh.
AddIndex(currentIndex + 2);
920 out_mesh.
AddIndex(currentIndex + 1);
921 out_mesh.
AddIndex(currentIndex + 3);
922 out_mesh.
AddIndex(currentIndex + 2);
928 size_t currentIndex = out_mesh.
GetVertices().size() + 1;
930 std::pair<geom::Vector3D, geom::Vector3D> edges =
934 director /= director.
Length();
941 if (s_current > s_end) {
947 director = edges.second - edges.first;
948 director /= director.
Length();
949 endmarking = edges.first + director * lane_mark_info.
width;
955 out_mesh.
AddIndex(currentIndex + 1);
956 out_mesh.
AddIndex(currentIndex + 2);
958 out_mesh.
AddIndex(currentIndex + 1);
959 out_mesh.
AddIndex(currentIndex + 3);
960 out_mesh.
AddIndex(currentIndex + 2);
1004 }
while (s_current < s_end);
1008 if (road_info_mark !=
nullptr)
1025 inout.push_back(std::make_unique<Mesh>(out_mesh));
1051 return {neighbor_info.
vertex, 0};
1053 if(abs(distance3D) < EPSILON) {
1054 return {neighbor_info.
vertex, 0};
1056 float weight = geom::Math::Clamp<float>(1.0f / distance3D, 0.0f, 100000.0f);
1066 return {neighbor_info.
vertex, weight};
1072 std::vector<std::unique_ptr<Mesh>> &lane_meshes) {
1075 using Point = Rtree::BPoint;
1077 for (
size_t lane_mesh_idx = 0; lane_mesh_idx < lane_meshes.size(); ++lane_mesh_idx) {
1078 auto& mesh = lane_meshes[lane_mesh_idx];
1079 for(
size_t i = 0; i < mesh->GetVerticesNum(); ++i) {
1080 auto& vertex = mesh->GetVertices()[i];
1081 Point point(vertex.x, vertex.y, vertex.z);
1082 if (i < 2 || i >= mesh->GetVerticesNum() - 2) {
1083 rtree.InsertElement({point, {&vertex, lane_mesh_idx,
true}});
1085 rtree.InsertElement({point, {&vertex, lane_mesh_idx,
false}});
1091 std::vector<VertexNeighbors> vertices_neighborhoods;
1092 for (
size_t lane_mesh_idx = 0; lane_mesh_idx < lane_meshes.size(); ++lane_mesh_idx) {
1093 auto& mesh = lane_meshes[lane_mesh_idx];
1094 for(
size_t i = 0; i < mesh->GetVerticesNum(); ++i) {
1095 if (i > 2 && i < mesh->GetVerticesNum() - 2) {
1096 auto& vertex = mesh->GetVertices()[i];
1097 Point point(vertex.x, vertex.y, vertex.z);
1098 auto closest_vertices = rtree.GetNearestNeighbours(point, 20);
1100 vertex_neighborhood.
vertex = &vertex;
1101 for(
auto& close_vertex : closest_vertices) {
1102 auto &vertex_info = close_vertex.second;
1103 if(&vertex == vertex_info.vertex) {
1107 road_param, {&vertex, lane_mesh_idx,
false}, vertex_info);
1108 if(vertex_weight.weight > 0)
1109 vertex_neighborhood.
neighbors.push_back(vertex_weight);
1111 vertices_neighborhoods.push_back(vertex_neighborhood);
1115 return vertices_neighborhoods;
1124 auto Laplacian = [&](
const Mesh::vertex_type* vertex,
const std::vector<VertexWeight> &neighbors) ->
double {
1126 double sum_weight = 0;
1127 for(
auto &element : neighbors) {
1128 sum += (element.vertex->z - vertex->
z)*element.weight;
1129 sum_weight += element.weight;
1132 return sum / sum_weight;
1137 double lambda = 0.5;
1138 int iterations = 100;
1139 for(
int iter = 0; iter < iterations; ++iter) {
1140 for (
auto& vertex_neighborhood : vertices_neighborhoods) {
1141 auto * vertex = vertex_neighborhood.vertex;
1142 vertex->
z +=
static_cast<float>(lambda*Laplacian(vertex, vertex_neighborhood.neighbors));
1146 for(
auto &mesh : lane_meshes) {
1150 return std::make_unique<Mesh>(out_mesh);
void GenerateLaneMarksForNotCenterLine(const road::LaneSection &lane_section, const road::Lane &lane, std::vector< std::unique_ptr< Mesh >> &inout, std::vector< std::string > &outinfo) const
static auto Distance(const Vector3D &a, const Vector3D &b)
Seting for map generation from opendrive without additional geometry.
void AddVertex(vertex_type vertex)
Appends a vertex to the vertices list.
double GetDistance() const
float same_lane_weight_multiplier
static VertexWeight ComputeVertexWeight(const MeshFactory::RoadParameters &road_param, const VertexInfo &vertex_info, const VertexInfo &neighbor_info)
bool IsValid() const
Check if the mesh can be valid or not.
std::unique_ptr< Mesh > Generate(const road::Road &road) const
Generates a mesh that defines a road.
std::unique_ptr< Mesh > GenerateSidewalk(const road::LaneSection &lane_section) const
Each lane within a road cross section can be provided with several road markentries.
bgi::rtree< SpatialTreeEntry, bgi::rstar< 16 > > Rtree
void AddIndex(index_type index)
Appends a index to the indexes list.
std::unique_ptr< Mesh > MergeAndSmooth(std::vector< std::unique_ptr< Mesh >> &lane_meshes) const
std::vector< VertexNeighbors > GetVertexNeighborhoodAndWeights(const MeshFactory::RoadParameters &road_param, std::vector< std::unique_ptr< Mesh >> &lane_meshes)
double GetDistance() const
void GenerateAllOrderedWithMaxLen(const road::Road &road, std::map< road::Lane::LaneType, std::vector< std::unique_ptr< Mesh >>> &roads) const
std::unique_ptr< Mesh > GenerateRightWall(const road::Lane &lane, const double s_start, const double s_end) const
Generates a wall-like mesh at the right side of the lane.
This file contains definitions of common data structures used in traffic manager. ...
void GenerateLaneSectionOrdered(const road::LaneSection &lane_section, std::map< carla::road::Lane::LaneType, std::vector< std::unique_ptr< Mesh >>> &result) const
Generates a mesh that defines a lane section.
void AddVertices(const std::vector< vertex_type > &vertices)
Appends a vertex to the vertices list.
Mesh::vertex_type * vertex
double vertex_width_resolution
void AddUVs(const std::vector< uv_type > &uv)
Appends uvs.
void AddMaterial(const std::string &material_name)
Starts applying a new material to the new added triangles.
void EndMaterial()
Stops applying the material to the new added triangles.
#define DEBUG_ASSERT(predicate)
void GenerateLaneMarksForCenterLine(const road::Road &road, const road::LaneSection &lane_section, const road::Lane &lane, std::vector< std::unique_ptr< Mesh >> &inout, std::vector< std::string > &outinfo) const
auto GetLaneSections() const
RoadParameters road_param
std::vector< std::unique_ptr< Mesh > > GenerateWithMaxLen(const road::Road &road) const
Generates a list of meshes that defines a road with a maximum length.
#define RELEASE_ASSERT(pred)
LaneType
Can be used as flags.
MeshFactory(rpc::OpendriveGenerationParameters params=rpc::OpendriveGenerationParameters())
std::vector< VertexWeight > neighbors
void AddTriangleStrip(const std::vector< vertex_type > &vertices)
Adds a triangle strip to the mesh, vertex order is counterclockwise.
std::unique_ptr< Mesh > GenerateLeftWall(const road::Lane &lane, const double s_start, const double s_end) const
Generates a wall-like mesh at the left side of the lane.
Mesh data container, validator and exporter.
const T * GetInfo(const double s) const
std::unique_ptr< Mesh > GenerateWalls(const road::LaneSection &lane_section) const
Genrates a mesh representing a wall on the road corners to avoid cars falling down.
static constexpr double MESH_EPSILON
std::map< LaneId, Lane > & GetLanes()
bool IsStraight() const
Checks whether the geometry is straight or not.
std::map< carla::road::Lane::LaneType, std::vector< std::unique_ptr< Mesh > > > GenerateOrderedWithMaxLen(const road::Road &road) const
Generates a list of meshes that defines a road with a maximum length.
std::vector< std::unique_ptr< Mesh > > GenerateWallsWithMaxLen(const road::Road &road) const
Generates a list of meshes that defines a road safety wall with a maximum length. ...
std::vector< std::unique_ptr< Mesh > > GenerateAllWithMaxLen(const road::Road &road) const
Generates a chunked road with all the features needed for simulation.
static constexpr double EPSILON
We use this epsilon to shift the waypoints away from the edges of the lane sections to avoid floating...
float vertex_width_resolution
void GenerateLaneMarkForRoad(const road::Road &road, std::vector< std::unique_ptr< Mesh >> &inout, std::vector< std::string > &outinfo) const
Parameters for the road generation.
Mesh::vertex_type * vertex
std::unique_ptr< Mesh > GenerateTesselated(const road::Lane &lane, const double s_start, const double s_end) const
Generates a mesh that defines a lane from a given s start and end with bigger tesselation.
const std::vector< vertex_type > & GetVertices() const
Rtree class working with 3D point clouds.
Mesh::vertex_type * vertex
void ApplyLateralOffset(float lateral_offset)
std::pair< geom::Vector3D, geom::Vector3D > GetCornerPositions(const double s, const float extra_width=0.f) const
Computes the location of the edges given a s.
element::DirectedPoint GetDirectedPointIn(const double s) const
Returns a directed point on the center of the road (lane 0), with the corresponding laneOffset and el...
float lane_ends_multiplier
float max_weight_distance