CARLA
 
载入中...
搜索中...
未找到
MeshFactory.cpp
浏览该文件的文档.
1// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
8
9#include <vector>
10
11#include <carla/geom/Vector3D.h>
12#include <carla/geom/Rtree.h>
15#include <carla/road/Map.h>
17
18namespace carla {
19namespace geom {
20
21 // MeshFactory构造函数,接受一个参数用于初始化路面相关参数
23 road_param.resolution = static_cast<float>(params.vertex_distance); // 设置顶点距离
24 road_param.max_road_len = static_cast<float>(params.max_road_length); // 设置最大道路长度
25 road_param.extra_lane_width = static_cast<float>(params.additional_width); // 设置额外车道宽度
26 road_param.wall_height = static_cast<float>(params.wall_height); // 设置墙体高度
27 road_param.vertex_width_resolution = static_cast<float>(params.vertex_width_resolution); // 设置顶点宽度分辨率
28 }
29
30 // 为避免浮点精度错误,使用此epsilon值将路径点从车道边缘移开
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();
33
34 // 根据路面生成网格
35 std::unique_ptr<Mesh> MeshFactory::Generate(const road::Road &road) const {
36 Mesh out_mesh; // 创建输出网格
37 for (auto &&lane_section : road.GetLaneSections()) { // 遍历所有车道段
38 out_mesh += *Generate(lane_section); // 生成每个车道段的网格并添加到输出网格中
39 }
40 return std::make_unique<Mesh>(out_mesh); // 返回生成的网格
41 }
42
43 // 根据车道段生成网格
44 std::unique_ptr<Mesh> MeshFactory::Generate(const road::LaneSection &lane_section) const {
45 Mesh out_mesh; // 创建输出网格
46 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的所有车道
47 out_mesh += *Generate(lane_pair.second); // 生成每条车道的网格并添加到输出网格中
48 }
49 return std::make_unique<Mesh>(out_mesh); // 返回生成的网格
50 }
51
52 // 根据车道生成网格,默认起始点和结束点
53 std::unique_ptr<Mesh> MeshFactory::Generate(const road::Lane &lane) const {
54 const double s_start = lane.GetDistance() + EPSILON; // 计算起始点
55 const double s_end = lane.GetDistance() + lane.GetLength() - EPSILON; // 计算结束点
56 return Generate(lane, s_start, s_end); // 调用重载函数生成网格
57 }
58
59 // 根据车道生成细分网格,默认起始点和结束点
60 std::unique_ptr<Mesh> MeshFactory::GenerateTesselated(const road::Lane& lane) const {
61 const double s_start = lane.GetDistance() + EPSILON; // 计算起始点
62 const double s_end = lane.GetDistance() + lane.GetLength() - EPSILON; // 计算结束点
63 return GenerateTesselated(lane, s_start, s_end); // 调用重载函数生成细分网格
64 }
65
66 // 根据车道和给定的起始、结束位置生成网格
67 std::unique_ptr<Mesh> MeshFactory::Generate(
68 const road::Lane& lane, const double s_start, const double s_end) const {
69 RELEASE_ASSERT(road_param.resolution > 0.0); // 确保分辨率大于0
70 DEBUG_ASSERT(s_start >= 0.0); // 确保起始点合法
71 DEBUG_ASSERT(s_end <= lane.GetDistance() + lane.GetLength()); // 确保结束点合法
72 DEBUG_ASSERT(s_end >= EPSILON); // 确保结束点大于Epsilon
73 DEBUG_ASSERT(s_start < s_end); // 确保起始点小于结束点
74
75 // ID为0的车道在OpenDRIVE中没有物理表示
76 Mesh out_mesh;
77 if (lane.GetId() == 0) {
78 return std::make_unique<Mesh>(out_mesh); // 返回空网格
79 }
80
81 double s_current = s_start; // 当前s值初始化为起始点
82
83 std::vector<geom::Vector3D> vertices; // 存储顶点的向量
84 if (lane.IsStraight()) { // 如果车道是直的
85 // 网格优化:如果车道是直的,只需在开始和结束处添加顶点
86 const auto edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); // 获取当前车道边缘位置
87 vertices.push_back(edges.first); // 添加左边缘顶点
88 vertices.push_back(edges.second); // 添加右边缘顶点
89 }
90 else {
91 // 遍历车道的's'并根据宽度存储顶点
92 do {
93 // 获取当前路径点的车道边缘位置
94 const auto edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width);
95 vertices.push_back(edges.first); // 添加左边缘顶点
96 vertices.push_back(edges.second); // 添加右边缘顶点
97
98 // 更新当前路径点的"s"
99 s_current += road_param.resolution; // 增加当前s值
100 } while (s_current < s_end); // 继续直到达到结束点
101 }
102
103 // 确保网格是连续的,并且车道之间没有间隙,
104 // 在车道的末尾添加几何形状
105 if (s_end - (s_current - road_param.resolution) > EPSILON) {
106 const auto edges = lane.GetCornerPositions(s_end - MESH_EPSILON, road_param.extra_lane_width); // 获取结束点的车道边缘位置
107 vertices.push_back(edges.first); // 添加左边缘顶点
108 vertices.push_back(edges.second); // 添加右边缘顶点
109 }
110
111 // 添加材质,创建三角形带并结束材质
112 out_mesh.AddMaterial(
113 lane.GetType() == road::Lane::LaneType::Sidewalk ? "sidewalk" : "road"); // 根据车道类型选择材质
114 out_mesh.AddTriangleStrip(vertices); // 添加三角形带
115 out_mesh.EndMaterial(); // 结束材质
116 return std::make_unique<Mesh>(out_mesh); // 返回生成的网格
117 }
118
119 std::unique_ptr<Mesh> MeshFactory::GenerateTesselated(
120 const road::Lane& lane, const double s_start, const double s_end) const { // 生成细分网格
121 RELEASE_ASSERT(road_param.resolution > 0.0); // 确保分辨率大于零
122 DEBUG_ASSERT(s_start >= 0.0); // 确保起始s值非负
123 DEBUG_ASSERT(s_end <= lane.GetDistance() + lane.GetLength()); // 确保结束s值在有效范围内
124 DEBUG_ASSERT(s_end >= EPSILON); // 确保结束s值大于最小值
125 DEBUG_ASSERT(s_start < s_end); // 确保起始s值小于结束s值
126 // lane_id为0的车道在OpenDRIVE中没有物理表示
127 Mesh out_mesh; // 创建网格对象
128 if (lane.GetId() == 0) { // 检查车道ID
129 return std::make_unique<Mesh>(out_mesh); // 如果ID为0,返回空网格
130 }
131 double s_current = s_start; // 初始化当前s值
132
133 std::vector<geom::Vector3D> vertices; // 存储顶点的向量
134 // 确保宽度方向上的最小顶点数为两个
135 const int vertices_in_width = road_param.vertex_width_resolution >= 2 ? road_param.vertex_width_resolution : 2; // 设置宽度方向上的顶点数
136 const int segments_number = vertices_in_width - 1; // 计算段数
137
138 std::vector<geom::Vector2D> uvs; // 存储UV坐标
139 int uvx = 0; // UV的X坐标
140 int uvy = 0; // UV的Y坐标
141 // 遍历车道的's'并根据其宽度存储顶点
142 do {
143 // 获取当前车道在当前位置的边缘位置
144 std::pair<geom::Vector3D, geom::Vector3D> edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); // 获取边缘位置
145 const geom::Vector3D segments_size = (edges.second - edges.first) / segments_number; // 计算每个段的大小
146 geom::Vector3D current_vertex = edges.first; // 当前顶点初始化为左边缘
147 uvx = 0; // 重置UV的X坐标
148 for (int i = 0; i < vertices_in_width; ++i) { // 遍历宽度方向的顶点
149 uvs.push_back(geom::Vector2D(uvx, uvy)); // 添加UV坐标
150 vertices.push_back(current_vertex); // 添加当前顶点
151 current_vertex = current_vertex + segments_size; // 更新当前顶点位置
152 uvx++; // 更新UV的X坐标
153 }
154 uvy++; // 更新UV的Y坐标
155 // 更新当前waypoint的"s"
156 s_current += road_param.resolution; // 增加当前s值
157 } while (s_current < s_end); // 当当前s值小于结束s值时继续
158
159 // 确保网格是连续的,没有道路之间的间隙,
160 // 在车道末尾添加几何体
161
162 if (s_end - (s_current - road_param.resolution) > EPSILON) { // 检查是否需要在末尾添加几何体
163 std::pair<carla::geom::Vector3D, carla::geom::Vector3D> edges =
164 lane.GetCornerPositions(s_end - MESH_EPSILON, road_param.extra_lane_width); // 获取结束位置的边缘
165 const geom::Vector3D segments_size = (edges.second - edges.first) / segments_number; // 计算段的大小
166 geom::Vector3D current_vertex = edges.first; // 当前顶点初始化为左边缘
167 uvx = 0; // 重置UV的X坐标
168 for (int i = 0; i < vertices_in_width; ++i) // 遍历宽度方向的顶点
169 {
170 uvs.push_back(geom::Vector2D(uvx, uvy)); // 添加UV坐标
171 vertices.push_back(current_vertex); // 添加当前顶点
172 current_vertex = current_vertex + segments_size; // 更新当前顶点位置
173 uvx++; // 更新UV的X坐标
174 }
175 }
176 out_mesh.AddVertices(vertices); // 添加顶点到网格
177 out_mesh.AddUVs(uvs); // 添加UV坐标到网格
178
179 // 添加材质,创建索引并结束材质
180 out_mesh.AddMaterial(
181 lane.GetType() == road::Lane::LaneType::Sidewalk ? "sidewalk" : "road"); // 根据车道类型选择材质
182
183 const size_t number_of_rows = (vertices.size() / vertices_in_width); // 计算行数
184
185 for (size_t i = 0; i < (number_of_rows - 1); ++i) { // 遍历行
186 for (size_t j = 0; j < vertices_in_width - 1; ++j) { // 遍历列
187 out_mesh.AddIndex( j + ( i * vertices_in_width ) + 1); // 添加索引
188 out_mesh.AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1); // 添加索引
189 out_mesh.AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1); // 添加索引
190
191 out_mesh.AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1); // 添加索引
192 out_mesh.AddIndex( ( j + 1 ) + ( ( i + 1 ) * vertices_in_width ) + 1); // 添加索引
193 out_mesh.AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1); // 添加索引
194 }
195 }
196 out_mesh.EndMaterial(); // 结束材质
197 return std::make_unique<Mesh>(out_mesh); // 返回生成的网格
198}
199
201 const road::LaneSection &lane_section,
202 std::map<carla::road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>>& result) const {
203
204 const int vertices_in_width = road_param.vertex_width_resolution >= 2 ? road_param.vertex_width_resolution : 2; // 确定每个车道宽度的顶点分辨率,至少为2
205 std::vector<size_t> redirections; // 用于存储已处理的车道ID
206 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的所有车道
207 auto it = std::find(redirections.begin(), redirections.end(), lane_pair.first); // 查找当前车道ID是否已存在
208 if ( it == redirections.end() ) { // 如果车道ID不存在,则添加
209 redirections.push_back(lane_pair.first); // 将新的车道ID添加到列表中
210 it = std::find(redirections.begin(), redirections.end(), lane_pair.first); // 重新查找当前车道ID的位置
211 }
212 size_t PosToAdd = it - redirections.begin(); // 计算当前车道ID在列表中的位置
213
214 Mesh out_mesh; // 创建一个新的网格对象
215 switch(lane_pair.second.GetType()) // 根据车道类型生成不同的网格
216 {
217 case road::Lane::LaneType::Driving: // 驾驶车道
218 case road::Lane::LaneType::Parking: // 停车车道
219 case road::Lane::LaneType::Bidirectional: // 双向车道
220 {
221 out_mesh += *GenerateTesselated(lane_pair.second); // 生成细分网格并添加到输出网格
222 break; // 结束当前case
223 }
224 case road::Lane::LaneType::Shoulder: // 应急车道
225 case road::Lane::LaneType::Sidewalk: // 人行道
226 case road::Lane::LaneType::Biking: // 自行车道
227 {
228 out_mesh += *GenerateSidewalk(lane_pair.second); // 生成人行道网格并添加到输出网格
229 break; // 结束当前case
230 }
231 default: // 其他类型的车道
232 {
233 out_mesh += *GenerateTesselated(lane_pair.second); // 默认生成细分网格并添加到输出网格
234 break; // 结束当前case
235 }
236 }
237
238 if( result[lane_pair.second.GetType()].size() <= PosToAdd ){ // 检查当前车道类型的网格数量是否小于等于位置索引
239 result[lane_pair.second.GetType()].push_back(std::make_unique<Mesh>(out_mesh)); // 如果满足条件,则添加新的网格到结果中
240 } else { // 如果已存在网格
241 uint32_t verticesinwidth = SelectVerticesInWidth(vertices_in_width, lane_pair.second.GetType()); // 选择适当的宽度顶点数量
242 (result[lane_pair.second.GetType()][PosToAdd])->ConcatMesh(out_mesh, verticesinwidth); // 将新生成的网格与现有网格合并
243 }
244 }
245 }
246
247std::unique_ptr<Mesh> MeshFactory::GenerateSidewalk(const road::LaneSection &lane_section) const{ // 定义生成侧步的方法,接受车道段作为参数
248 Mesh out_mesh; // 创建一个输出网格
249 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的所有车道
250 const double s_start = lane_pair.second.GetDistance() + EPSILON; // 计算开始的s参数
251 const double s_end = lane_pair.second.GetDistance() + lane_pair.second.GetLength() - EPSILON; // 计算结束的s参数
252 out_mesh += *GenerateSidewalk(lane_pair.second, s_start, s_end); // 生成车道的侧步网格并添加到输出网格
253 }
254 return std::make_unique<Mesh>(out_mesh); // 返回创建的网格
255}
256std::unique_ptr<Mesh> MeshFactory::GenerateSidewalk(const road::Lane &lane) const{ // 定义生成侧步的方法,接受车道作为参数
257 const double s_start = lane.GetDistance() + EPSILON; // 计算开始的s参数
258 const double s_end = lane.GetDistance() + lane.GetLength() - EPSILON; // 计算结束的s参数
259 return GenerateSidewalk(lane, s_start, s_end); // 调用重载方法生成侧步网格
260}
261
262std::unique_ptr<Mesh> MeshFactory::GenerateSidewalk( // 重载方法,接受车道及其起始和结束s参数
263 const road::Lane &lane, const double s_start,
264 const double s_end ) const {
265
266 RELEASE_ASSERT(road_param.resolution > 0.0); // 确保道路参数的分辨率大于零
267 DEBUG_ASSERT(s_start >= 0.0); // 确保开始的s参数非负
268 DEBUG_ASSERT(s_end <= lane.GetDistance() + lane.GetLength()); // 确保结束的s参数不超过车道长度
269 DEBUG_ASSERT(s_end >= EPSILON); // 确保结束的s参数大于或等于一个小的正值
270 DEBUG_ASSERT(s_start < s_end); // 确保开始的s参数小于结束的s参数
271 // lane_id为0的车道在OpenDRIVE中没有物理表示
272 Mesh out_mesh; // 创建一个输出网格
273 if (lane.GetId() == 0) { // 如果车道ID为0
274 return std::make_unique<Mesh>(out_mesh); // 返回空网格
275 }
276 double s_current = s_start; // 初始化当前s为起始s值
277
278 std::vector<geom::Vector3D> vertices; // 存储顶点的向量
279 // 确保宽度上至少有两个顶点
280 const int vertices_in_width = 6; // 每行中的顶点数量
281 const int segments_number = vertices_in_width - 1; // 计算段落数量
282 std::vector<geom::Vector2D> uvs; // 存储纹理坐标的向量
283 int uvy = 0; // 纹理坐标y轴索引
284
285 // 遍历车道的's'值,根据其宽度存储顶点
286 do {
287 // 获取当前路点处车道边缘的位置
288 std::pair<geom::Vector3D, geom::Vector3D> edges =
290
291 geom::Vector3D low_vertex_first = edges.first - geom::Vector3D(0,0,1); // 计算第一个低顶点
292 geom::Vector3D low_vertex_second = edges.second - geom::Vector3D(0,0,1); // 计算第二个低顶点
293 vertices.push_back(low_vertex_first); // 添加第一个低顶点到顶点列表
294 uvs.push_back(geom::Vector2D(0, uvy)); // 添加相应的纹理坐标
295
296 vertices.push_back(edges.first); // 添加第一个边缘顶点
297 uvs.push_back(geom::Vector2D(1, uvy)); // 添加相应的纹理坐标
298
299 vertices.push_back(edges.first); // 重复添加第一个边缘顶点
300 uvs.push_back(geom::Vector2D(1, uvy)); // 添加相应的纹理坐标
301
302 vertices.push_back(edges.second); // 添加第二个边缘顶点
303 uvs.push_back(geom::Vector2D(2, uvy)); // 添加相应的纹理坐标
304
305 vertices.push_back(edges.second); // 重复添加第二个边缘顶点
306 uvs.push_back(geom::Vector2D(2, uvy)); // 添加相应的纹理坐标
307
308 vertices.push_back(low_vertex_second); // 添加第二个低顶点到顶点列表
309 uvs.push_back(geom::Vector2D(3, uvy)); // 添加相应的纹理坐标
310
311 // 更新当前路点的"s"值
312 s_current += road_param.resolution; // 增加当前的"s"值
313 uvy++; // 增加y轴纹理坐标索引
314 } while (s_current < s_end); // 当当前s小于结束s值时继续循环
315
316 // 确保网格是连续的,并且道路之间没有缝隙,
317 // 在车道的最末尾添加几何体
318
319 if (s_end - (s_current - road_param.resolution) > EPSILON) { // 检查是否需要额外的顶点
320 std::pair<carla::geom::Vector3D, carla::geom::Vector3D> edges =
322
323 geom::Vector3D low_vertex_first = edges.first - geom::Vector3D(0,0,1); // 计算第一个低顶点
324 geom::Vector3D low_vertex_second = edges.second - geom::Vector3D(0,0,1); // 计算第二个低顶点
325
326 vertices.push_back(low_vertex_first); // 添加第一个低顶点到顶点列表
327 uvs.push_back(geom::Vector2D(0, uvy)); // 添加相应的纹理坐标
328
329 vertices.push_back(edges.first); // 添加第一个边缘顶点
330 uvs.push_back(geom::Vector2D(1, uvy)); // 添加相应的纹理坐标
331
332 vertices.push_back(edges.first); // 重复添加第一个边缘顶点
333 uvs.push_back(geom::Vector2D(1, uvy)); // 添加相应的纹理坐标
334
335 vertices.push_back(edges.second); // 添加第二个边缘顶点
336 uvs.push_back(geom::Vector2D(2, uvy)); // 添加相应的纹理坐标
337
338 vertices.push_back(edges.second); // 重复添加第二个边缘顶点
339 uvs.push_back(geom::Vector2D(2, uvy)); // 添加相应的纹理坐标
340
341 vertices.push_back(low_vertex_second); // 添加第二个低顶点到顶点列表
342 uvs.push_back(geom::Vector2D(3, uvy)); // 添加相应的纹理坐标
343
344 }
345
346 out_mesh.AddVertices(vertices); // 将所有顶点添加到输出网格
347 out_mesh.AddUVs(uvs); // 将所有纹理坐标添加到输出网格
348 // 添加渐变材料,创建条带并结束材料
349 out_mesh.AddMaterial(
350 lane.GetType() == road::Lane::LaneType::Sidewalk ? "sidewalk" : "road"); // 根据车道类型添加材料
351
352 const int number_of_rows = (vertices.size() / vertices_in_width); // 计算行数
353
354 for (size_t i = 0; i < (number_of_rows - 1); ++i) { // 遍历每一行
355 for (size_t j = 0; j < vertices_in_width - 1; ++j) { // 遍历每一行的每个顶点
356
357 if(j == 1 || j == 3){ // 跳过特定的顶点索引
358 continue; // 继续下一个循环
359 }
360
361 out_mesh.AddIndex( j + ( i * vertices_in_width ) + 1); // 添加三角形索引
362 out_mesh.AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1); // 添加三角形索引
363 out_mesh.AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1); // 添加三角形索引
364
365 out_mesh.AddIndex( ( j + 1 ) + ( i * vertices_in_width ) + 1); // 添加三角形索引
366 out_mesh.AddIndex( ( j + 1 ) + ( ( i + 1 ) * vertices_in_width ) + 1); // 添加三角形索引
367 out_mesh.AddIndex( j + ( ( i + 1 ) * vertices_in_width ) + 1); // 添加三角形索引
368
369 }
370 }
371 out_mesh.EndMaterial(); // 结束材料定义
372 return std::make_unique<Mesh>(out_mesh); // 返回创建的网格对象
373}
374std::unique_ptr<Mesh> MeshFactory::GenerateWalls(const road::LaneSection &lane_section) const {
375 Mesh out_mesh; // 创建一个输出网格
376
377 // 确定最小和最大车道的ID
378 const auto min_lane = lane_section.GetLanes().begin()->first == 0 ?
379 1 : lane_section.GetLanes().begin()->first; // 如果最小车道ID为0,则设置为1
380 const auto max_lane = lane_section.GetLanes().rbegin()->first == 0 ?
381 -1 : lane_section.GetLanes().rbegin()->first; // 如果最大车道ID为0,则设置为-1
382
383 // 遍历所有车道
384 for (auto &&lane_pair : lane_section.GetLanes()) {
385 const auto &lane = lane_pair.second; // 获取当前车道
386 const double s_start = lane.GetDistance() + EPSILON; // 车道起始位置
387 const double s_end = lane.GetDistance() + lane.GetLength() - EPSILON; // 车道结束位置
388 if (lane.GetId() == max_lane) { // 如果是最大车道
389 out_mesh += *GenerateLeftWall(lane, s_start, s_end); // 生成左墙并添加到输出网格
390 }
391 if (lane.GetId() == min_lane) { // 如果是最小车道
392 out_mesh += *GenerateRightWall(lane, s_start, s_end); // 生成右墙并添加到输出网格
393 }
394 }
395 return std::make_unique<Mesh>(out_mesh); // 返回包含生成墙体的网格
396}
397
398std::unique_ptr<Mesh> MeshFactory::GenerateRightWall(
399 const road::Lane &lane, const double s_start, const double s_end) const {
400 RELEASE_ASSERT(road_param.resolution > 0.0); // 确保分辨率大于0
401 DEBUG_ASSERT(s_start >= 0.0); // 确保起始位置合法
402 DEBUG_ASSERT(s_end <= lane.GetDistance() + lane.GetLength()); // 确保结束位置合法
403 DEBUG_ASSERT(s_end >= EPSILON); // 确保结束位置大于一个小值
404 DEBUG_ASSERT(s_start < s_end); // 确保起始位置小于结束位置
405 // ID为0的车道在OpenDRIVE中没有物理表示
406 Mesh out_mesh; // 创建输出网格
407 if (lane.GetId() == 0) { // 如果车道ID为0
408 return std::make_unique<Mesh>(out_mesh); // 返回空网格
409 }
410 double s_current = s_start; // 当前s值初始化为起始位置
411 const geom::Vector3D height_vector = geom::Vector3D(0.f, 0.f, road_param.wall_height); // 墙体高度向量
412
413 std::vector<geom::Vector3D> r_vertices; // 存储右墙顶点的容器
414 if (lane.IsStraight()) { // 如果车道是直的
415 // 网格优化:如果车道是直的,只需在起始和结束位置添加顶点
416 const auto edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); // 获取边缘位置
417 r_vertices.push_back(edges.first + height_vector); // 添加上边缘顶点
418 r_vertices.push_back(edges.first); // 添加下边缘顶点
419 } else {
420 // 遍历车道的's'并根据宽度存储顶点
421 do {
422 // 获取当前s位置的车道边缘位置
423 const auto edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width);
424 r_vertices.push_back(edges.first + height_vector); // 添加上边缘顶点
425 r_vertices.push_back(edges.first); // 添加下边缘顶点
426
427 // 更新当前的s值
428 s_current += road_param.resolution; // 将s值增加分辨率
429 } while(s_current < s_end); // 当当前s值小于结束s值时继续
430 }
431
432 // 确保网格是连续的,且车道之间没有缝隙,
433 // 在车道末尾添加几何体
434 if (s_end - (s_current - road_param.resolution) > EPSILON) {
435 const auto edges = lane.GetCornerPositions(s_end - MESH_EPSILON, road_param.extra_lane_width); // 获取结束位置的边缘
436 r_vertices.push_back(edges.first + height_vector); // 添加上边缘顶点
437 r_vertices.push_back(edges.first); // 添加下边缘顶点
438 }
439
440 // 添加合适的材质,创建三角形带,并结束材质定义
441 out_mesh.AddMaterial(
442 lane.GetType() == road::Lane::LaneType::Sidewalk ? "sidewalk" : "road"); // 根据车道类型添加材质
443 out_mesh.AddTriangleStrip(r_vertices); // 添加三角带
444 out_mesh.EndMaterial(); // 结束材质定义
445 return std::make_unique<Mesh>(out_mesh); // 返回包含右墙的网格
446}
447
448std::unique_ptr<Mesh> MeshFactory::GenerateLeftWall(
449 const road::Lane &lane, const double s_start, const double s_end) const {
450 RELEASE_ASSERT(road_param.resolution > 0.0); // 确保分辨率大于0
451 DEBUG_ASSERT(s_start >= 0.0); // 确保起始位置合法
452 DEBUG_ASSERT(s_end <= lane.GetDistance() + lane.GetLength()); // 确保结束位置合法
453 DEBUG_ASSERT(s_end >= EPSILON); // 确保结束位置大于一个小值
454 DEBUG_ASSERT(s_start < s_end); // 确保起始位置小于结束位置
455 // ID为0的车道在OpenDRIVE中没有物理表示
456 Mesh out_mesh; // 创建输出网格
457 if (lane.GetId() == 0) { // 如果车道ID为0
458 return std::make_unique<Mesh>(out_mesh); // 返回空网格
459 }
460
461 double s_current = s_start; // 初始化当前的s值为起始位置
462 const geom::Vector3D height_vector = geom::Vector3D(0.f, 0.f, road_param.wall_height); // 创建高度向量,表示墙体的高度
463
464 std::vector<geom::Vector3D> l_vertices; // 存储左墙顶点的容器
465 if (lane.IsStraight()) { // 如果车道是直的
466 // 网格优化:如果车道是直的,只需在起始和结束位置添加顶点
467 const auto edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); // 获取边缘位置
468 l_vertices.push_back(edges.second); // 添加下边缘顶点
469 l_vertices.push_back(edges.second + height_vector); // 添加上边缘顶点
470 } else {
471 // 遍历车道的's'并根据宽度存储顶点
472 do {
473 // 获取当前s位置的车道边缘位置
474 const auto edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width);
475 l_vertices.push_back(edges.second); // 添加下边缘顶点
476 l_vertices.push_back(edges.second + height_vector); // 添加上边缘顶点
477
478 // 更新当前的s值
479 s_current += road_param.resolution; // 将s值增加分辨率
480 } while(s_current < s_end); // 当当前s值小于结束s值时继续
481 }
482
483 // 确保网格是连续的,且车道之间没有缝隙,
484 // 在车道末尾添加几何体
485 if (s_end - (s_current - road_param.resolution) > EPSILON) { // 如果s_end与当前s的差距大于小值
486 const auto edges = lane.GetCornerPositions(s_end - MESH_EPSILON, road_param.extra_lane_width); // 获取结束位置的边缘
487 l_vertices.push_back(edges.second); // 添加下边缘顶点
488 l_vertices.push_back(edges.second + height_vector); // 添加上边缘顶点
489 }
490
491 // 添加合适的材质,创建三角形带,并结束材质定义
492 out_mesh.AddMaterial(
493 lane.GetType() == road::Lane::LaneType::Sidewalk ? "sidewalk" : "road"); // 根据车道类型添加材质
494 out_mesh.AddTriangleStrip(l_vertices); // 添加三角带
495 out_mesh.EndMaterial(); // 结束材质定义
496 return std::make_unique<Mesh>(out_mesh); // 返回包含左墙的网格
497 }
498
499 std::vector<std::unique_ptr<Mesh>> MeshFactory::GenerateWithMaxLen(
500 const road::Road &road) const { // 根据道路生成最大长度的网格
501 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list; // 存储生成的网格指针的列表
502 for (auto &&lane_section : road.GetLaneSections()) { // 遍历道路的每个车道段
503 auto section_uptr_list = GenerateWithMaxLen(lane_section); // 生成当前车道段的网格
504 mesh_uptr_list.insert(
505 mesh_uptr_list.end(),
506 std::make_move_iterator(section_uptr_list.begin()), // 移动当前车道段网格到总列表
507 std::make_move_iterator(section_uptr_list.end())); // 移动结束迭代器
508 }
509 return mesh_uptr_list; // 返回所有生成的网格列表
510 }
511
512
513std::vector<std::unique_ptr<Mesh>> MeshFactory::GenerateWithMaxLen(
514 const road::LaneSection &lane_section) const { // 定义一个成员函数,生成具有最大长度的Mesh
515 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list; // 创建一个存储唯一指针的向量,用于保存Mesh
516 if (lane_section.GetLength() < road_param.max_road_len) { // 如果车道段的长度小于最大路段长度
517 mesh_uptr_list.emplace_back(Generate(lane_section)); // 直接生成Mesh并加入到列表中
518 } else { // 否则(车道段较长)
519 double s_current = lane_section.GetDistance() + EPSILON; // 当前距离设置为车道段起点加一个小值
520 const double s_end = lane_section.GetDistance() + lane_section.GetLength() - EPSILON; // 终点距离计算
521 while(s_current + road_param.max_road_len < s_end) { // 当当前距离加上最大路段长度小于终点时
522 const auto s_until = s_current + road_param.max_road_len; // 计算本次生成的终点
523 Mesh lane_section_mesh; // 创建一个Mesh对象用于存储车道段的Mesh
524 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的所有车道
525 lane_section_mesh += *Generate(lane_pair.second, s_current, s_until); // 生成车道的Mesh并累加
526 }
527 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh)); // 将生成的Mesh加入到列表中
528 s_current = s_until; // 更新当前距离为本次生成的终点
529 }
530 if (s_end - s_current > EPSILON) { // 如果还有剩余未处理的距离
531 Mesh lane_section_mesh; // 创建新的Mesh对象
532 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的所有车道
533 lane_section_mesh += *Generate(lane_pair.second, s_current, s_end); // 生成剩余部分的Mesh并累加
534 }
535 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh)); // 将最后生成的Mesh加入到列表中
536 }
537 }
538 return mesh_uptr_list; // 返回生成的Mesh列表
539 }
540
541std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> MeshFactory::GenerateOrderedWithMaxLen(
542 const road::Road &road) const { // 定义一个成员函数,根据车道类型生成有序的Mesh列表
543 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> mesh_uptr_list; // 创建一个映射,用于存储不同类型车道的Mesh列表
544 for (auto &&lane_section : road.GetLaneSections()) { // 遍历道路中的每个车道段
545 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> section_uptr_list = GenerateOrderedWithMaxLen(lane_section); // 递归调用生成车道段的Mesh列表
546 mesh_uptr_list.insert( // 将生成的车道段Mesh列表插入到总列表中
547 std::make_move_iterator(section_uptr_list.begin()), // 移动迭代器,避免拷贝
548 std::make_move_iterator(section_uptr_list.end())); // 移动到末尾
549 }
550 return mesh_uptr_list; // 返回按类型排序的Mesh列表
551 }
552
553std::map<road::Lane::LaneType, std::vector<std::unique_ptr<Mesh>>> MeshFactory::GenerateOrderedWithMaxLen(
554 const road::LaneSection& lane_section) const { // 定义函数,生成具有最大长度的有序Mesh
555 const int vertices_in_width = road_param.vertex_width_resolution >= 2 ? road_param.vertex_width_resolution : 2; // 确定宽度方向上的顶点数量
556 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<Mesh>>> mesh_uptr_list; // 创建一个映射,用于存储不同车道类型的Mesh指针
557
558 if (lane_section.GetLength() < road_param.max_road_len) { // 如果车道段长度小于最大道路长度
559 GenerateLaneSectionOrdered(lane_section, mesh_uptr_list); // 生成有序车道段Mesh
560 }
561 else {
562 double s_current = lane_section.GetDistance() + EPSILON; // 当前的s值,初始为车道段的起始距离加上一个非常小的值
563 const double s_end = lane_section.GetDistance() + lane_section.GetLength() - EPSILON; // 结束的s值
564 std::vector<size_t> redirections; // 用于存储车道索引的重定向
565
566 while (s_current + road_param.max_road_len < s_end) { // 当当前s值加上最大道路长度小于结束的s值时
567 const auto s_until = s_current + road_param.max_road_len; // 计算当前片段的结束s值
568
569 for (auto&& lane_pair : lane_section.GetLanes()) { // 遍历车道段中的每个车道
570 Mesh lane_section_mesh; // 创建一个Mesh对象用于存储当前车道段的Mesh
571
572 switch (lane_pair.second.GetType()) // 根据车道类型生成Mesh
573 {
574 case road::Lane::LaneType::Driving: // 驾驶车道
575 case road::Lane::LaneType::Parking: // 停车车道
576 case road::Lane::LaneType::Bidirectional: // 双向车道
577 {
578 lane_section_mesh += *GenerateTesselated(lane_pair.second, s_current, s_until); // 生成细分网格并累加到mesh中
579 break;
580 }
581 case road::Lane::LaneType::Shoulder: // 路肩
582 case road::Lane::LaneType::Sidewalk: // 人行道
583 case road::Lane::LaneType::Biking: // 自行车道
584 {
585 lane_section_mesh += *GenerateSidewalk(lane_pair.second, s_current, s_until); // 生成人行道Mesh并累加
586 break;
587 }
588 default: // 默认情况
589 {
590 lane_section_mesh += *GenerateTesselated(lane_pair.second, s_current, s_until); // 生成细分网格并累加
591 break;
592 }
593 }
594 auto it = std::find(redirections.begin(), redirections.end(), lane_pair.first); // 查找当前车道的索引
595 if (it == redirections.end()) { // 如果未找到
596 redirections.push_back(lane_pair.first); // 将车道索引添加到重定向列表中
597 it = std::find(redirections.begin(), redirections.end(), lane_pair.first); // 再次查找以获取迭代器
598 }
599
600 size_t PosToAdd = it - redirections.begin(); // 计算要添加的位置
601 if (mesh_uptr_list[lane_pair.second.GetType()].size() <= PosToAdd) { // 如果该类型的Mesh数量不足
602 mesh_uptr_list[lane_pair.second.GetType()].push_back(std::make_unique<Mesh>(lane_section_mesh)); // 新建一个Mesh并添加
603 }
604 else {
605 uint32_t verticesinwidth = SelectVerticesInWidth(vertices_in_width, lane_pair.second.GetType()); // 根据车道类型选择宽度方向的顶点数
606 (mesh_uptr_list[lane_pair.second.GetType()][PosToAdd])->ConcatMesh(lane_section_mesh, verticesinwidth); // 拼接当前Mesh到已有Mesh中
607 }
608 }
609 s_current = s_until; // 更新当前s值
610 }
611 if (s_end - s_current > EPSILON) { // 如果还有剩余的段落
612 for (auto&& lane_pair : lane_section.GetLanes()) { // 遍历车道段中的每个车道
613 Mesh lane_section_mesh; // 创建一个Mesh对象
614
615 switch (lane_pair.second.GetType()) // 根据车道类型生成Mesh
616 {
617 case road::Lane::LaneType::Driving: // 驾驶车道
618 case road::Lane::LaneType::Parking: // 停车车道
619 case road::Lane::LaneType::Bidirectional: // 双向车道
620 {
621 lane_section_mesh += *GenerateTesselated(lane_pair.second, s_current, s_end); // 生成细分网格并累加
622 break;
623 }
624 case road::Lane::LaneType::Shoulder: // 路肩
625 case road::Lane::LaneType::Sidewalk: // 人行道
626 case road::Lane::LaneType::Biking: // 自行车道
627 {
628 lane_section_mesh += *GenerateSidewalk(lane_pair.second, s_current, s_end); // 生成人行道Mesh并累加
629 break;
630 }
631 default: // 默认情况
632 {
633 lane_section_mesh += *GenerateTesselated(lane_pair.second, s_current, s_end); // 生成细分网格并累加
634 break;
635 }
636 }
637
638 auto it = std::find(redirections.begin(), redirections.end(), lane_pair.first); // 查找当前车道的索引
639 if (it == redirections.end()) { // 如果未找到该车道索引
640 redirections.push_back(lane_pair.first); // 将车道索引添加到重定向列表中
641 it = std::find(redirections.begin(), redirections.end(), lane_pair.first); // 再次查找以获取迭代器
642 }
643
644 size_t PosToAdd = it - redirections.begin(); // 计算要添加的位置
645
646 if (mesh_uptr_list[lane_pair.second.GetType()].size() <= PosToAdd) { // 如果该类型的Mesh数量不足
647 mesh_uptr_list[lane_pair.second.GetType()].push_back(std::make_unique<Mesh>(lane_section_mesh)); // 新建一个Mesh并添加到列表中
648 }
649 else {
650 *(mesh_uptr_list[lane_pair.second.GetType()][PosToAdd]) += lane_section_mesh; // 将当前Mesh累加到已有Mesh中
651 }
652 }
653 }
654 }
655 return mesh_uptr_list;
656}
657
658 std::vector<std::unique_ptr<Mesh>> MeshFactory::GenerateWallsWithMaxLen(
659 const road::Road &road) const { // 根据给定的道路生成最大长度的墙体
660 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list; // 存储生成的Mesh指针列表
661 for (auto &&lane_section : road.GetLaneSections()) { // 遍历每个车道段
662 auto section_uptr_list = GenerateWallsWithMaxLen(lane_section); // 生成该车道段的墙体
663 mesh_uptr_list.insert(
664 mesh_uptr_list.end(),
665 std::make_move_iterator(section_uptr_list.begin()), // 将生成的Mesh移动到主列表中
666 std::make_move_iterator(section_uptr_list.end()));
667 }
668 return mesh_uptr_list; // 返回生成的Mesh列表
669 }
670
671 std::vector<std::unique_ptr<Mesh>> MeshFactory::GenerateWallsWithMaxLen(
672 const road::LaneSection &lane_section) const { // 根据给定的车道段生成最大长度的墙体
673 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list; // 存储生成的Mesh指针列表
674
675 const auto min_lane = lane_section.GetLanes().begin()->first == 0 ? // 获取最小车道ID,如果是0则设为1
676 1 : lane_section.GetLanes().begin()->first;
677 const auto max_lane = lane_section.GetLanes().rbegin()->first == 0 ? // 获取最大车道ID,如果是0则设为-1
678 -1 : lane_section.GetLanes().rbegin()->first;
679
680 if (lane_section.GetLength() < road_param.max_road_len) { // 如果车道段长度小于最大道路长度
681 mesh_uptr_list.emplace_back(GenerateWalls(lane_section)); // 直接生成墙体并添加到列表
682 } else { // 如果车道段长度大于等于最大道路长度
683 double s_current = lane_section.GetDistance() + EPSILON; // 当前距离加上一个小值(避免浮点误差)
684 const double s_end = lane_section.GetDistance() + lane_section.GetLength() - EPSILON; // 结束距离
685 while(s_current + road_param.max_road_len < s_end) { // 当当前距离加上最大长度小于结束距离时
686 const auto s_until = s_current + road_param.max_road_len; // 计算下一个段的结束位置
687 Mesh lane_section_mesh; // 创建一个Mesh对象用于存储当前段的墙体
688 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的每个车道
689 const auto &lane = lane_pair.second; // 获取当前车道
690 if (lane.GetId() == max_lane) { // 如果是最大车道
691 lane_section_mesh += *GenerateLeftWall(lane, s_current, s_until); // 生成左侧墙体并累加
692 }
693 if (lane.GetId() == min_lane) { // 如果是最小车道
694 lane_section_mesh += *GenerateRightWall(lane, s_current, s_until); // 生成右侧墙体并累加
695 }
696 }
697 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh)); // 将生成的Mesh添加到列表
698 s_current = s_until; // 更新当前距离
699 }
700 if (s_end - s_current > EPSILON) { // 如果结束距离与当前距离之间的差值大于一个小值
701 Mesh lane_section_mesh; // 创建一个Mesh对象用于存储最后一段的墙体
702 for (auto &&lane_pair : lane_section.GetLanes()) { // 遍历车道段中的每个车道
703 const auto &lane = lane_pair.second; // 获取当前车道
704 if (lane.GetId() == max_lane) { // 如果是最大车道
705 lane_section_mesh += *GenerateLeftWall(lane, s_current, s_end); // 生成左侧墙体并累加
706 }
707 if (lane.GetId() == min_lane) { // 如果是最小车道
708 lane_section_mesh += *GenerateRightWall(lane, s_current, s_end); // 生成右侧墙体并累加
709 }
710 }
711 mesh_uptr_list.emplace_back(std::make_unique<Mesh>(lane_section_mesh)); // 将生成的Mesh添加到列表
712 }
713 }
714 return mesh_uptr_list; // 返回生成的Mesh列表
715 }
716
717std::vector<std::unique_ptr<Mesh>> MeshFactory::GenerateAllWithMaxLen(
718 const road::Road &road) const { // 定义一个函数,生成具有最大长度的所有网格
719 std::vector<std::unique_ptr<Mesh>> mesh_uptr_list; // 创建一个唯一指针的网格列表
720
721 // 获取道路网格
722 auto roads = GenerateWithMaxLen(road); // 生成最大长度的道路网格
723 mesh_uptr_list.insert(
724 mesh_uptr_list.end(),
725 std::make_move_iterator(roads.begin()), // 移动道路网格到列表中
726 std::make_move_iterator(roads.end())); // 移动道路网格到列表中
727
728 //如果不是交叉口则获取墙体网格
729 if (!road.IsJunction()) { // 如果不是交叉口
730 auto walls = GenerateWallsWithMaxLen(road); // 生成最大长度的墙体网格
731
732 if (roads.size() == walls.size()) { // 如果道路和墙体的数量相同
733 for (size_t i = 0; i < walls.size(); ++i) { // 遍历墙体网格
734 *mesh_uptr_list[i] += *walls[i]; // 将墙体网格合并到对应的道路网格中
735 }
736 } else { // 如果数量不同
737 mesh_uptr_list.insert(
738 mesh_uptr_list.end(),
739 std::make_move_iterator(walls.begin()), // 移动墙体网格到列表中
740 std::make_move_iterator(walls.end())); // 移动墙体网格到列表中
741 }
742 }
743
744 return mesh_uptr_list; // 返回生成的网格列表
745 }
746
748 const road::Road &road,
749 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>>& roads
750 ) const { // 定义一个函数,按顺序生成具有最大长度的所有网格
751
752 // Get road meshes 获取道路网格
753 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<Mesh>>> result = GenerateOrderedWithMaxLen(road); // 生成有序的最大长度道路网格
754 for (auto &pair_map : result) { // 遍历结果中的每一对
755 std::vector<std::unique_ptr<Mesh>>& origin = roads[pair_map.first]; // 获取原始网格列表
756 std::vector<std::unique_ptr<Mesh>>& source = pair_map.second; // 获取源网格列表
757 std::move(source.begin(), source.end(), std::back_inserter(origin)); // 将源网格移动到原始网格列表中
758 }
759 }
760
762 const road::Road& road,
763 std::vector<std::unique_ptr<Mesh>>& inout,
764 std::vector<std::string>& outinfo ) const // 定义一个函数,为道路生成车道标记
765 {
766 for (auto&& lane_section : road.GetLaneSections()) { // 遍历道路的车道段
767 for (auto&& lane : lane_section.GetLanes()) { // 遍历车道
768 if (lane.first != 0) { // 如果车道索引不为0
769 switch(lane.second.GetType()) // 根据车道类型选择操作
770 {
771 case road::Lane::LaneType::Driving: // 驾驶车道
772 case road::Lane::LaneType::Parking: // 停车车道
773 case road::Lane::LaneType::Bidirectional: // 双向车道
774 {
775 GenerateLaneMarksForNotCenterLine(lane_section, lane.second, inout, outinfo); // 为非中心线生成车道标记
776 outinfo.push_back("white"); // 添加白色到输出信息
777 break; // 退出switch
778 }
779 }
780 } else { // 如果车道索引为0
781 if(lane.second.GetType() == road::Lane::LaneType::None ){ // 如果车道类型为无
782 GenerateLaneMarksForCenterLine(road, lane_section, lane.second, inout, outinfo); // 为中心线生成车道标记
783 outinfo.push_back("yellow"); // 添加黄色到输出信息
784 }
785 }
786 }
787 }
788 }
789
791 const road::LaneSection& lane_section, // 道路车道段
792 const road::Lane& lane, // 道路车道
793 std::vector<std::unique_ptr<Mesh>>& inout, // 输入输出网格
794 std::vector<std::string>& outinfo ) const { // 输出信息
795 Mesh out_mesh; // 输出网格
796 const double s_start = lane_section.GetDistance(); // 起始距离
797 const double s_end = lane_section.GetDistance() + lane_section.GetLength(); // 结束距离
798 double s_current = s_start; // 当前距离
799 std::vector<geom::Vector3D> vertices; // 顶点向量
800 std::vector<size_t> indices; // 索引向量
801
802 do {
803 // 获取车道信息
804 const carla::road::element::RoadInfoMarkRecord* road_info_mark = lane.GetInfo<carla::road::element::RoadInfoMarkRecord>(s_current); // 获取当前距离的标记信息
805 if (road_info_mark != nullptr) { // 如果标记信息存在
806 carla::road::element::LaneMarking lane_mark_info(*road_info_mark); // 创建车道标记信息对象
807
808 switch (lane_mark_info.type) { // 根据标记类型进行处理
809 case carla::road::element::LaneMarking::Type::Solid: { // 实线的情况
810 size_t currentIndex = out_mesh.GetVertices().size() + 1; // 当前索引
811
812 std::pair<geom::Vector3D, geom::Vector3D> edges =
813 ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); // 计算边缘
814
815 out_mesh.AddVertex(edges.first); // 添加第一个顶点
816 out_mesh.AddVertex(edges.second); // 添加第二个顶点
817
818 out_mesh.AddIndex(currentIndex); // 添加索引
819 out_mesh.AddIndex(currentIndex + 1); // 添加索引
820 out_mesh.AddIndex(currentIndex + 2); // 添加索引
821
822 out_mesh.AddIndex(currentIndex + 1); // 添加索引
823 out_mesh.AddIndex(currentIndex + 3); // 添加索引
824 out_mesh.AddIndex(currentIndex + 2); // 添加索引
825
826 s_current += road_param.resolution; // 更新当前距离
827 break;
828 }
829 case carla::road::element::LaneMarking::Type::Broken: { // 虚线的情况
830 size_t currentIndex = out_mesh.GetVertices().size() + 1; // 当前索引
831
832 std::pair<geom::Vector3D, geom::Vector3D> edges =
833 ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); // 计算边缘
834
835 out_mesh.AddVertex(edges.first); // 添加第一个顶点
836 out_mesh.AddVertex(edges.second); // 添加第二个顶点
837
838 s_current += road_param.resolution * 3; // 更新当前距离
839 if (s_current > s_end) // 如果超出结束距离
840 {
841 s_current = s_end; // 将当前距离设置为结束距离
842 }
843
844 edges = ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); // 计算新的边缘
845
846 out_mesh.AddVertex(edges.first); // 添加第一个顶点
847 out_mesh.AddVertex(edges.second); // 添加第二个顶点
848
849 out_mesh.AddIndex(currentIndex); // 添加索引
850 out_mesh.AddIndex(currentIndex + 1); // 添加索引
851 out_mesh.AddIndex(currentIndex + 2); // 添加索引
852
853 out_mesh.AddIndex(currentIndex + 1); // 添加索引
854 out_mesh.AddIndex(currentIndex + 3); // 添加索引
855 out_mesh.AddIndex(currentIndex + 2); // 添加索引
856
857 s_current += road_param.resolution * 3; // 更新当前距离
858
859 break;
860 }
862 s_current += road_param.resolution; // 更新当前距离
863 break;
864 }
866 s_current += road_param.resolution; // 更新当前距离
867 break;
868 }
870 s_current += road_param.resolution; // 更新当前距离
871 break;
872 }
874 s_current += road_param.resolution; // 更新当前距离
875 break;
876 }
878 s_current += road_param.resolution; // 更新当前距离
879 break;
880 }
882 s_current += road_param.resolution; // 更新当前距离
883 break;
884 }
886 s_current += road_param.resolution; // 更新当前距离
887 break;
888 }
890 s_current += road_param.resolution; // 更新当前距离
891 break;
892 }
893 default: { // 默认情况
894 s_current += road_param.resolution; // 更新当前距离
895 break;
896 }
897 }
898 }
899 } while (s_current < s_end); // 当当前距离小于结束距离时继续循环
900
901 if (out_mesh.IsValid()) { // 如果输出网格有效
902 const carla::road::element::RoadInfoMarkRecord* road_info_mark = lane.GetInfo<carla::road::element::RoadInfoMarkRecord>(s_current); // 获取当前距离的标记信息
903 if (road_info_mark != nullptr) { // 如果标记信息存在
904 carla::road::element::LaneMarking lane_mark_info(*road_info_mark); // 创建车道标记信息对象
905
906 std::pair<geom::Vector3D, geom::Vector3D> edges =
907 ComputeEdgesForLanemark(lane_section, lane, s_end, lane_mark_info.width); // 计算结束距离的边缘
908
909 out_mesh.AddVertex(edges.first); // 添加第一个顶点
910 out_mesh.AddVertex(edges.second); // 添加第二个顶点
911 }
912 inout.push_back(std::make_unique<Mesh>(out_mesh)); // 将输出网格添加到输入输出中
913 }
914 }
915
916
918 const road::Road& road,
919 const road::LaneSection& lane_section,
920 const road::Lane& lane,
921 std::vector<std::unique_ptr<Mesh>>& inout,
922 std::vector<std::string>& outinfo ) const
923 {
924 Mesh out_mesh; // 初始化输出网格
925 const double s_start = lane_section.GetDistance(); // 获取车道段的起始距离
926 const double s_end = lane_section.GetDistance() + lane_section.GetLength(); // 获取车道段的结束距离
927 double s_current = s_start; // 当前距离从起始距离开始
928 std::vector<geom::Vector3D> vertices; // 顶点容器
929 std::vector<size_t> indices; // 索引容器
930
931 do {
932 // 获取车道信息
934 if (road_info_mark != nullptr) { // 如果标记信息不为空
935 carla::road::element::LaneMarking lane_mark_info(*road_info_mark); // 创建车道标记信息
936
937 switch (lane_mark_info.type) { // 根据标记类型进行处理
939 size_t currentIndex = out_mesh.GetVertices().size() + 1; // 当前顶点索引
940
941 carla::road::element::DirectedPoint rightpoint = road.GetDirectedPointIn(s_current); // 获取右侧点
942 carla::road::element::DirectedPoint leftpoint = rightpoint; // 左侧点初始化为右侧点
943
944 rightpoint.ApplyLateralOffset(lane_mark_info.width * 0.5); // 应用右侧偏移
945 leftpoint.ApplyLateralOffset(lane_mark_info.width * -0.5); // 应用左侧偏移
946
947 // Unreal的Y轴处理
948 rightpoint.location.y *= -1; // 反转右侧点的Y坐标
949 leftpoint.location.y *= -1; // 反转左侧点的Y坐标
950
951 out_mesh.AddVertex(rightpoint.location); // 添加右侧点到网格
952 out_mesh.AddVertex(leftpoint.location); // 添加左侧点到网格
953
954 out_mesh.AddIndex(currentIndex); // 添加索引
955 out_mesh.AddIndex(currentIndex + 1); // 添加索引
956 out_mesh.AddIndex(currentIndex + 2); // 添加索引
957
958 out_mesh.AddIndex(currentIndex + 1); // 添加索引
959 out_mesh.AddIndex(currentIndex + 3); // 添加索引
960 out_mesh.AddIndex(currentIndex + 2); // 添加索引
961
962 s_current += road_param.resolution; // 更新当前距离
963 break;
964 }
966 size_t currentIndex = out_mesh.GetVertices().size() + 1; // 当前顶点索引
967
968 std::pair<geom::Vector3D, geom::Vector3D> edges =
969 ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); // 计算边缘
970
971 out_mesh.AddVertex(edges.first); // 添加边缘第一个点到网格
972 out_mesh.AddVertex(edges.second); // 添加边缘第二个点到网格
973
974 s_current += road_param.resolution * 3; // 更新当前距离
975 if (s_current > s_end) { // 如果当前距离超过结束距离
976 s_current = s_end; // 修正当前距离为结束距离
977 }
978
979 edges = ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); // 计算下一个边缘
980
981 out_mesh.AddVertex(edges.first); // 添加下一个边缘第一个点到网格
982 out_mesh.AddVertex(edges.second); // 添加下一个边缘第二个点到网格
983
984 out_mesh.AddIndex(currentIndex); // 添加索引
985 out_mesh.AddIndex(currentIndex + 1); // 添加索引
986 out_mesh.AddIndex(currentIndex + 2); // 添加索引
987
988 out_mesh.AddIndex(currentIndex + 1); // 添加索引
989 out_mesh.AddIndex(currentIndex + 3); // 添加索引
990 out_mesh.AddIndex(currentIndex + 2); // 添加索引
991
992 s_current += road_param.resolution * 3; // 更新当前距离
993
994 break;
995 }
996 case carla::road::element::LaneMarking::Type::SolidSolid: { // 实线-实线标记
997 s_current += road_param.resolution; // 当前距离增加分辨率
998 break;
999 }
1000 case carla::road::element::LaneMarking::Type::SolidBroken: { // 实线-实线标记
1001 s_current += road_param.resolution; // 当前距离增加分辨率
1002 break;
1003 }
1004 case carla::road::element::LaneMarking::Type::BrokenSolid: { //虚线-实线标记
1005 s_current += road_param.resolution; // 当前距离增加分辨率
1006 break;
1007 }
1008 case carla::road::element::LaneMarking::Type::BrokenBroken: { // 虚线-虚线标记
1009 s_current += road_param.resolution; // 当前距离增加分辨率
1010 break;
1011 }
1013 s_current += road_param.resolution; // 当前距离增加分辨率
1014 break;
1015 }
1017 s_current += road_param.resolution; // 当前距离增加分辨率
1018 break;
1019 }
1020 case carla::road::element::LaneMarking::Type::Curb: { // 路缘标记
1021 s_current += road_param.resolution; // 当前距离增加分辨率
1022 break;
1023 }
1024 case carla::road::element::LaneMarking::Type::Other: { // 其他类型标记
1025 s_current += road_param.resolution; // 当前距离增加分辨率
1026 break;
1027 }
1028 default: {
1029 s_current += road_param.resolution; // 当前距离增加分辨率
1030 break;
1031 }
1032 }
1033 }
1034 } while (s_current < s_end); // 循环直到当前距离小于结束距离
1035
1036 if (out_mesh.IsValid()) { // 如果输出网格有效
1037 const carla::road::element::RoadInfoMarkRecord* road_info_mark = lane.GetInfo<carla::road::element::RoadInfoMarkRecord>(s_current); // 获取道路信息标记记录
1038 if (road_info_mark != nullptr) // 如果道路信息标记不为空
1039 {
1040 carla::road::element::LaneMarking lane_mark_info(*road_info_mark); // 创建车道标记信息
1041 carla::road::element::DirectedPoint rightpoint = road.GetDirectedPointIn(s_current); // 获取当前距离的右侧点
1042 carla::road::element::DirectedPoint leftpoint = rightpoint; // 左侧点初始化为右侧点
1043
1044 rightpoint.ApplyLateralOffset(lane_mark_info.width * 0.5f); // 右侧点应用横向偏移
1045 leftpoint.ApplyLateralOffset(lane_mark_info.width * -0.5f); // 左侧点应用横向偏移
1046
1047 // Unreal的Y轴处理
1048 rightpoint.location.y *= -1; // 反转右侧点的Y轴
1049 leftpoint.location.y *= -1; // 反转左侧点的Y轴
1050
1051 out_mesh.AddVertex(rightpoint.location); // 向输出网格添加右侧点
1052 out_mesh.AddVertex(leftpoint.location); // 向输出网格添加左侧点
1053
1054 }
1055 inout.push_back(std::make_unique<Mesh>(out_mesh)); // 将输出网格添加到输出列表
1056 }
1057 }
1058
1059 struct VertexWeight { // 顶点权重结构
1060 Mesh::vertex_type* vertex; // 顶点指针
1061 double weight; // 权重值
1062 };
1063 struct VertexNeighbors { // 顶点邻居结构
1064 Mesh::vertex_type* vertex; // 顶点指针
1065 std::vector<VertexWeight> neighbors; // 邻居顶点权重列表
1066 };
1067 struct VertexInfo { // 顶点信息结构
1068 Mesh::vertex_type * vertex; // 顶点指针
1069 size_t lane_mesh_idx; // 车道网格索引
1070 bool is_static; // 是否为静态顶点
1071 };
1072
1073 // 计算邻居顶点权重的辅助函数
1075 const MeshFactory::RoadParameters &road_param, // 道路参数
1076 const VertexInfo &vertex_info, // 顶点信息
1077 const VertexInfo &neighbor_info) { // 邻居信息
1078 const float distance3D = geom::Math::Distance(*vertex_info.vertex, *neighbor_info.vertex); // 计算三维距离
1079 // 忽略超过一定距离的顶点
1080 if(distance3D > road_param.max_weight_distance) {
1081 return {neighbor_info.vertex, 0}; // 超过最大权重距离,返回权重为0
1082 }
1083 if(abs(distance3D) < EPSILON) { // 如果距离小于极小值
1084 return {neighbor_info.vertex, 0}; // 返回权重为0
1085 }
1086 float weight = geom::Math::Clamp<float>(1.0f / distance3D, 0.0f, 100000.0f); // 计算权重并限制范围
1087
1088 // 对于同一车道的顶点增加额外权重
1089 if(vertex_info.lane_mesh_idx == neighbor_info.lane_mesh_idx) {
1090 weight *= road_param.same_lane_weight_multiplier; // 乘以同车道权重因子
1091 // 对于固定顶点进一步增加权重
1092 if(neighbor_info.is_static) {
1093 weight *= road_param.lane_ends_multiplier; / 乘以车道结束权重因子
1094 }
1095 }
1096 return {neighbor_info.vertex, weight}; // 返回邻居顶点和计算的权重
1097 }
1098 // 辅助函数,计算顶点的邻域及其权重
1099 std::vector<VertexNeighbors> GetVertexNeighborhoodAndWeights(
1100 const MeshFactory::RoadParameters &road_param, // 道路参数
1101 std::vector<std::unique_ptr<Mesh>> &lane_meshes) { // 车道网格
1102 // 构建R树以进行邻域查询
1103 using Rtree = geom::PointCloudRtree<VertexInfo>; // R树类型
1104 using Point = Rtree::BPoint; // 点类型
1105 Rtree rtree; // 创建R树实例
1106 for (size_t lane_mesh_idx = 0; lane_mesh_idx < lane_meshes.size(); ++lane_mesh_idx) { // 遍历每个车道网格
1107 auto& mesh = lane_meshes[lane_mesh_idx]; // 获取当前网格
1108 for(size_t i = 0; i < mesh->GetVerticesNum(); ++i) { // 遍历每个顶点
1109 auto& vertex = mesh->GetVertices()[i]; // 获取当前顶点
1110 Point point(vertex.x, vertex.y, vertex.z); // 创建点对象
1111 if (i < 2 || i >= mesh->GetVerticesNum() - 2) { // 判断顶点是否为边界顶点
1112 rtree.InsertElement({point, {&vertex, lane_mesh_idx, true}}); // 插入边界顶点到R树
1113 } else {
1114 rtree.InsertElement({point, {&vertex, lane_mesh_idx, false}}); // 插入非边界顶点到R树
1115 }
1116 }
1117 }
1118
1119 // 查找每个顶点的邻居并计算它们的权重
1120 std::vector<VertexNeighbors> vertices_neighborhoods; // 顶点邻域集合
1121 for (size_t lane_mesh_idx = 0; lane_mesh_idx < lane_meshes.size(); ++lane_mesh_idx) { // 遍历每个车道网格
1122 auto& mesh = lane_meshes[lane_mesh_idx]; // 获取当前网格
1123 for(size_t i = 0; i < mesh->GetVerticesNum(); ++i) { // 遍历每个顶点
1124 if (i > 2 && i < mesh->GetVerticesNum() - 2) { // 排除边界顶点
1125 auto& vertex = mesh->GetVertices()[i]; // 获取当前顶点
1126 Point point(vertex.x, vertex.y, vertex.z); // 创建点对象
1127 auto closest_vertices = rtree.GetNearestNeighbours(point, 20); // 查询最近的20个顶点
1128 VertexNeighbors vertex_neighborhood; // 创建顶点邻域对象
1129 vertex_neighborhood.vertex = &vertex; // 设置当前顶点
1130 for(auto& close_vertex : closest_vertices) { // 遍历最近的顶点
1131 auto &vertex_info = close_vertex.second; // 获取顶点信息
1132 if(&vertex == vertex_info.vertex) { // 如果是自身,跳过
1133 continue;
1134 }
1135 auto vertex_weight = ComputeVertexWeight( // 计算顶点权重
1136 road_param, {&vertex, lane_mesh_idx, false}, vertex_info);
1137 if(vertex_weight.weight > 0) // 如果权重大于0
1138 vertex_neighborhood.neighbors.push_back(vertex_weight); // 添加到邻域中
1139 }
1140 vertices_neighborhoods.push_back(vertex_neighborhood); // 将邻域添加到结果中
1141 }
1142 }
1143 }
1144 return vertices_neighborhoods; // 返回所有顶点的邻域
1145}
1146
1147std::unique_ptr<Mesh> MeshFactory::MergeAndSmooth(std::vector<std::unique_ptr<Mesh>> &lane_meshes) const {
1148 geom::Mesh out_mesh; // 创建一个输出网格对象
1149
1150 auto vertices_neighborhoods = GetVertexNeighborhoodAndWeights(road_param, lane_meshes); // 获取顶点邻域和权重
1151
1152 // 拉普拉斯函数
1153 auto Laplacian = [&](const Mesh::vertex_type* vertex, const std::vector<VertexWeight> &neighbors) -> double {
1154 double sum = 0; // 初始化总和
1155 double sum_weight = 0; // 初始化权重总和
1156 for(auto &element : neighbors) { // 遍历邻居
1157 sum += (element.vertex->z - vertex->z)*element.weight; // 计算高度差乘以权重的累加
1158 sum_weight += element.weight; // 累加权重
1159 }
1160 if(sum_weight > 0) // 如果权重大于0
1161 return sum / sum_weight; // 返回平均值
1162 else
1163 return 0; // 否则返回0
1164 };
1165
1166 // 运行迭代算法
1167 double lambda = 0.5; // 设置拉普拉斯平滑的参数
1168 int iterations = 100; // 设置迭代次数
1169 for(int iter = 0; iter < iterations; ++iter) { // 进行迭代
1170 for (auto& vertex_neighborhood : vertices_neighborhoods) { // 遍历每个顶点的邻域
1171 auto * vertex = vertex_neighborhood.vertex; // 获取当前顶点
1172 vertex->z += static_cast<float>(lambda*Laplacian(vertex, vertex_neighborhood.neighbors)); // 更新顶点高度
1173 }
1174 }
1175
1176 for(auto &mesh : lane_meshes) { // 遍历所有车道网格
1177 out_mesh += *mesh; // 将每个网格添加到输出网格中
1178 }
1179
1180 return std::make_unique<Mesh>(out_mesh); // 返回新的网格对象
1181}
1182
1183uint32_t MeshFactory::SelectVerticesInWidth(uint32_t default_num_vertices, road::Lane::LaneType type) {
1184 switch(type) { // 根据车道类型选择顶点数量
1185 case road::Lane::LaneType::Driving: // 驾驶车道
1186 case road::Lane::LaneType::Parking: // 停车车道
1187 case road::Lane::LaneType::Bidirectional: // 双向车道
1188 {
1189 return default_num_vertices; // 返回默认顶点数量
1190 }
1191 case road::Lane::LaneType::Shoulder: // 应急车道
1192 case road::Lane::LaneType::Sidewalk: // 人行道
1193 case road::Lane::LaneType::Biking: // 自行车道
1194 {
1195 return 6; // 返回固定的6个顶点
1196 }
1197 default: // 其他类型
1198 {
1199 return 2; // 返回2个顶点
1200 }
1201 }
1202}
1203
1204std::pair<geom::Vector3D, geom::Vector3D> MeshFactory::ComputeEdgesForLanemark(
1205 const road::LaneSection& lane_section, // 车道段
1206 const road::Lane& lane, // 车道
1207 const double s_current, // 当前参数
1208 const double lanemark_width) const { // 车道标记宽度
1209 std::pair<geom::Vector3D, geom::Vector3D> edges =
1210 lane.GetCornerPositions(s_current, road_param.extra_lane_width); // 获取车道边缘位置
1211
1212 geom::Vector3D director; // 方向向量
1213 if (edges.first != edges.second) { // 如果两个边缘位置不同
1214 director = edges.second - edges.first; // 计算方向向量
1215 director /= director.Length(); // 标准化方向向量
1216 } else { // 如果边缘位置相同
1217 const std::map<road::LaneId, road::Lane> & lanes = lane_section.GetLanes(); // 获取车道映射
1218 for (const auto& lane_pair : lanes) { // 遍历每个车道
1219 std::pair<geom::Vector3D, geom::Vector3D> another_edge =
1220 lane_pair.second.GetCornerPositions(s_current, road_param.extra_lane_width); // 获取另一个车道的边缘位置
1221 if (another_edge.first != another_edge.second) { // 如果边缘位置不同
1222 director = another_edge.second - another_edge.first; // 计算方向向量
1223 director /= director.Length(); // 标准化方向向量
1224 break; // 退出循环
1225 }
1226 }
1227 }
1228 geom::Vector3D endmarking = edges.first + director * lanemark_width; // 计算车道标记的结束位置
1229 return std::make_pair(edges.first, endmarking); // 返回边缘位置对
1230 }
1231
1232} // namespace geom
1233} // namespace carla
#define DEBUG_ASSERT(predicate)
Definition Debug.h:68
#define RELEASE_ASSERT(pred)
Definition Debug.h:94
static auto Distance(const Vector3D &a, const Vector3D &b)
Definition Math.h:90
static uint32_t SelectVerticesInWidth(uint32_t default_num_vertices, road::Lane::LaneType type)
在给定车道类型下选择的宽度内的顶点数量
std::unique_ptr< Mesh > GenerateRightWall(const road::Lane &lane, const double s_start, const double s_end) const
在车道的右侧生成一个墙状网格
std::unique_ptr< Mesh > GenerateSidewalk(const road::LaneSection &lane_section) const
生成车道段的人行道网格
std::unique_ptr< Mesh > GenerateLeftWall(const road::Lane &lane, const double s_start, const double s_end) const
在车道的左侧生成一个墙状网格
std::unique_ptr< Mesh > MergeAndSmooth(std::vector< std::unique_ptr< Mesh > > &lane_meshes) const
合并并平滑多个车道网格
std::pair< geom::Vector3D, geom::Vector3D > ComputeEdgesForLanemark(const road::LaneSection &lane_section, const road::Lane &lane, const double s_current, const double lanemark_width) const
计算车道标记的当前s位置两侧的点
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
仅为中心线(ID为0的线)生成车道标记
std::vector< std::unique_ptr< Mesh > > GenerateWallsWithMaxLen(const road::Road &road) const
生成一个定义道路安全墙的网格列表,限制最大长度
void GenerateLaneMarkForRoad(const road::Road &road, std::vector< std::unique_ptr< Mesh > > &inout, std::vector< std::string > &outinfo) const
为道路生成车道标记
MeshFactory(rpc::OpendriveGenerationParameters params=rpc::OpendriveGenerationParameters())
RoadParameters road_param
std::unique_ptr< Mesh > Generate(const road::Road &road) const
生成定义一条道路的网格
void GenerateLaneMarksForNotCenterLine(const road::LaneSection &lane_section, const road::Lane &lane, std::vector< std::unique_ptr< Mesh > > &inout, std::vector< std::string > &outinfo) const
为非中心线(即ID不为0的所有线)生成车道标记
void GenerateLaneSectionOrdered(const road::LaneSection &lane_section, std::map< carla::road::Lane::LaneType, std::vector< std::unique_ptr< Mesh > > > &result) const
生成按顺序排列的车道段网格
std::unique_ptr< Mesh > GenerateTesselated(const road::Lane &lane, const double s_start, const double s_end) const
用更高的细分生成从给定的s起始和结束的车道网格
std::vector< std::unique_ptr< Mesh > > GenerateAllWithMaxLen(const road::Road &road) const
生成带有所有模拟所需特性的分块道路
std::vector< std::unique_ptr< Mesh > > GenerateWithMaxLen(const road::Road &road) const
生成一个定义道路的网格列表,限制最大长度
std::map< carla::road::Lane::LaneType, std::vector< std::unique_ptr< Mesh > > > GenerateOrderedWithMaxLen(const road::Road &road) const
生成一个定义道路的按顺序排列的网格列表,限制最大长度
std::unique_ptr< Mesh > GenerateWalls(const road::LaneSection &lane_section) const
生成一个网格,表示道路角落的墙,以避免车辆掉下去
void GenerateAllOrderedWithMaxLen(const road::Road &road, std::map< road::Lane::LaneType, std::vector< std::unique_ptr< Mesh > > > &roads) const
生成按顺序排列的道路网格,限制最大长度
网格数据容器、验证器和导出器。
Definition Mesh.h:43
void AddIndex(index_type index)
将索引附加到索引列表。
Definition Mesh.cpp:132
void AddVertex(vertex_type vertex)
将顶点附加到顶点列表。
Definition Mesh.cpp:120
void AddVertices(const std::vector< vertex_type > &vertices)
将顶点附加到顶点列表。
Definition Mesh.cpp:124
bool IsValid() const
检查网格是否有效。
Definition Mesh.cpp:20
void AddUVs(const std::vector< uv_type > &uv)
添加纹理映射坐标(Texture-Mapping Coordinates, UV)
Definition Mesh.cpp:140
void AddMaterial(const std::string &material_name)
开始将新材质应用到新添加的三角形。
Definition Mesh.cpp:144
void EndMaterial()
停止将材质应用到新添加的三角形。
Definition Mesh.cpp:160
void AddTriangleStrip(const std::vector< vertex_type > &vertices)
向网格添加三角形带,顶点顺序为逆时针。
Definition Mesh.cpp:52
const std::vector< vertex_type > & GetVertices() const
Definition Mesh.cpp:284
PointCloudRtree 类用于处理 3D 点云。 将类型 T 的元素与 3D 点关联,用于快速 k-NN 搜索。
Definition Rtree.h:34
定义两个嵌套的命名空间:carla和geom。
double GetDistance() const
std::map< LaneId, Lane > & GetLanes()
bool IsStraight() const
检查几何形状是否是直线
const T * GetInfo(const double s) const
Definition Lane.h:79
LaneType
可以作为标志使用
Definition Lane.h:29
LaneType GetType() const
double GetDistance() const
std::pair< geom::Vector3D, geom::Vector3D > GetCornerPositions(const double s, const float extra_width=0.f) const
计算给定位置s的车道边缘位置
LaneId GetId() const
double GetLength() const
auto GetLaneSections() const
Definition Road.h:120
element::DirectedPoint GetDirectedPointIn(const double s) const
返回指定距离的中心点(车道 0)的导向点
bool IsJunction() const
每条车道在道路横截面内可以提供多个道路标记条目。 道路标记信息定义了车道外边界的线条样式。 对于左侧车道,这是左边界;对于右侧车道,这是右边界。 左右车道之间的分隔线样式由零号车道(即中央车道)的道路标...
static constexpr double EPSILON
static VertexWeight ComputeVertexWeight(const MeshFactory::RoadParameters &road_param, const VertexInfo &vertex_info, const VertexInfo &neighbor_info)
static constexpr double MESH_EPSILON
std::vector< VertexNeighbors > GetVertexNeighborhoodAndWeights(const MeshFactory::RoadParameters &road_param, std::vector< std::unique_ptr< Mesh > > &lane_meshes)
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
Mesh::vertex_type * vertex
std::vector< VertexWeight > neighbors
Mesh::vertex_type * vertex
void ApplyLateralOffset(float lateral_offset)
Definition Geometry.cpp:45
Seting for map generation from opendrive without additional geometry