CARLA
Mesh.h
Go to the documentation of this file.
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 
7 #pragma once
8 
9 #include <vector>
10 
11 #include <carla/geom/Vector3D.h>
12 #include <carla/geom/Vector2D.h>
13 
14 #ifdef LIBCARLA_INCLUDED_FROM_UE4
18 #endif // LIBCARLA_INCLUDED_FROM_UE4
19 
20 namespace carla {
21 namespace geom {
22 
23  /// Material that references the vertex index start and end of
24  /// a mesh where it is affecting.
25  struct MeshMaterial {
26 
28  const std::string &new_name,
29  size_t start = 0u,
30  size_t end = 0u)
31  : name(new_name),
32  index_start(start),
33  index_end(end) {}
34 
35  const std::string name;
36 
37  size_t index_start;
38 
39  size_t index_end;
40 
41  };
42 
43  /// Mesh data container, validator and exporter.
44  class Mesh {
45  public:
46 
49  using index_type = size_t;
50  using uv_type = Vector2D;
52 
53  // =========================================================================
54  // -- Constructor ----------------------------------------------------------
55  // =========================================================================
56 
57  Mesh(const std::vector<vertex_type> &vertices = {},
58  const std::vector<normal_type> &normals = {},
59  const std::vector<index_type> &indexes = {},
60  const std::vector<uv_type> &uvs = {})
61  : _vertices(vertices),
62  _normals(normals),
63  _indexes(indexes),
64  _uvs(uvs) {}
65 
66  // =========================================================================
67  // -- Validate methods -----------------------------------------------------
68  // =========================================================================
69 
70  /// Check if the mesh can be valid or not.
71  bool IsValid() const;
72 
73  // =========================================================================
74  // -- Mesh build methods ---------------------------------------------------
75  // =========================================================================
76 
77  /// Adds a triangle strip to the mesh, vertex order is counterclockwise.
78  void AddTriangleStrip(const std::vector<vertex_type> &vertices);
79 
80  /// Adds a triangle fan to the mesh, vertex order is counterclockwise.
81  void AddTriangleFan(const std::vector<vertex_type> &vertices);
82 
83  /// Appends a vertex to the vertices list.
84  void AddVertex(vertex_type vertex);
85 
86  /// Appends a vertex to the vertices list.
87  void AddVertices(const std::vector<vertex_type> &vertices);
88 
89  /// Appends a normal to the normal list.
90  void AddNormal(normal_type normal);
91 
92  /// Appends a index to the indexes list.
93  void AddIndex(index_type index);
94 
95  /// Appends a vertex to the vertices list, they will be read 3 in 3.
96  void AddUV(uv_type uv);
97 
98  /// Appends uvs.
99  void AddUVs(const std::vector<uv_type> & uv);
100 
101  /// Starts applying a new material to the new added triangles.
102  void AddMaterial(const std::string &material_name);
103 
104  /// Stops applying the material to the new added triangles.
105  void EndMaterial();
106 
107  // =========================================================================
108  // -- Export methods -------------------------------------------------------
109  // =========================================================================
110 
111  /// Returns a string containing the mesh encoded in OBJ.
112  /// Units are in meters. It is in Unreal space.
113  std::string GenerateOBJ() const;
114 
115  /// Returns a string containing the mesh encoded in OBJ.
116  /// Units are in meters. This function exports the OBJ file
117  /// specifically to be consumed by Recast library.
118  /// Changes the build face direction and the coordinate space.
119  std::string GenerateOBJForRecast() const;
120 
121  /// Returns a string containing the mesh encoded in PLY.
122  /// Units are in meters.
123  std::string GeneratePLY() const;
124 
125  // =========================================================================
126  // -- Other methods --------------------------------------------------------
127  // =========================================================================
128 
129  const std::vector<vertex_type> &GetVertices() const;
130 
131  std::vector<vertex_type> &GetVertices();
132 
133  size_t GetVerticesNum() const;
134 
135  const std::vector<normal_type> &GetNormals() const;
136 
137  const std::vector<index_type>& GetIndexes() const;
138 
139  std::vector<index_type> &GetIndexes();
140 
141  size_t GetIndexesNum() const;
142 
143  const std::vector<uv_type> &GetUVs() const;
144 
145  const std::vector<material_type> &GetMaterials() const;
146 
147  /// Returns the index of the last added vertex (number of vertices).
148  size_t GetLastVertexIndex() const;
149 
150  /// Merges two meshes into a single mesh
151  Mesh& ConcatMesh(const Mesh& rhs, int num_vertices_to_link);
152 
153  /// Merges two meshes into a single mesh
154  Mesh &operator+=(const Mesh &rhs);
155 
156  friend Mesh operator+(const Mesh &lhs, const Mesh &rhs);
157 
158  // =========================================================================
159  // -- Conversions to UE4 types ---------------------------------------------
160  // =========================================================================
161 
162 #ifdef LIBCARLA_INCLUDED_FROM_UE4
163 
164  operator FProceduralCustomMesh() const {
166 
167  // Build the mesh
168  for (const auto Vertex : GetVertices())
169  {
170  // From meters to centimeters
171  Mesh.Vertices.Add(FVector{1e2f * Vertex.x, 1e2f * Vertex.y, 1e2f * Vertex.z});
172  }
173 
174  const auto Indexes = GetIndexes();
175  TArray<FTriIndices> TriIndices;
176  for (auto i = 0u; i < Indexes.size(); i += 3)
177  {
178  FTriIndices Triangle;
179  // "-1" since mesh indexes in Unreal starts from index 0.
180  Mesh.Triangles.Add(Indexes[i] - 1);
181  // Since Unreal's coords are left handed, invert the last 2 indices.
182  Mesh.Triangles.Add(Indexes[i + 2] - 1);
183  Mesh.Triangles.Add(Indexes[i + 1] - 1);
184 
185  Triangle.v0 = Indexes[i] - 1;
186  Triangle.v1 = Indexes[i + 2] - 1;
187  Triangle.v2 = Indexes[i + 1] - 1;
188  TriIndices.Add(Triangle);
189  }
190 
191  // Compute the normals
192  TArray<FVector> Normals;
193  Mesh.Normals.Init(FVector::UpVector, Mesh.Vertices.Num());
194 
195  for (const auto &Triangle : TriIndices) {
196  FVector Normal;
197  const FVector U = Mesh.Vertices[Triangle.v1] - Mesh.Vertices[Triangle.v0];
198  const FVector V = Mesh.Vertices[Triangle.v2] - Mesh.Vertices[Triangle.v0];
199  Normal.X = (U.Y * V.Z) - (U.Z * V.Y);
200  Normal.Y = (U.Z * V.X) - (U.X * V.Z);
201  Normal.Z = (U.X * V.Y) - (U.Y * V.X);
202  Normal = -Normal;
203  Normal = Normal.GetSafeNormal(.0001f);
204  if (Normal != FVector::ZeroVector)
205  {
206  // fix to prevent ugly x-fighting in geometries with very large curvatures,
207  // ensures that all road geometry is facing upwards
208  if (FVector::DotProduct(Normal, FVector(0,0,1)) < 0)
209  {
210  Normal = -Normal;
211  }
212  Mesh.Normals[Triangle.v0] = Normal;
213  Mesh.Normals[Triangle.v1] = Normal;
214  Mesh.Normals[Triangle.v2] = Normal;
215  }
216  }
217 
218  for (const auto uv : GetUVs())
219  {
220  // From meters to centimeters
221  Mesh.UV0.Add(FVector2D{uv.x, uv.y});
222  }
223 
224  return Mesh;
225  }
226 
227 #endif // LIBCARLA_INCLUDED_FROM_UE4
228 
229  private:
230 
231  // =========================================================================
232  // -- Private data members -------------------------------------------------
233  // =========================================================================
234 
235  std::vector<vertex_type> _vertices;
236 
237  std::vector<normal_type> _normals;
238 
239  std::vector<index_type> _indexes;
240 
241  std::vector<uv_type> _uvs;
242 
243  std::vector<material_type> _materials;
244  };
245 
246 } // namespace geom
247 } // namespace carla
size_t index_type
Definition: Mesh.h:49
A definition of a Carla Mesh.
const std::string name
Definition: Mesh.h:35
Mesh operator+(const Mesh &lhs, const Mesh &rhs)
Definition: Mesh.cpp:385
MeshMaterial(const std::string &new_name, size_t start=0u, size_t end=0u)
Definition: Mesh.h:27
TArray< FVector2D > UV0
Mesh(const std::vector< vertex_type > &vertices={}, const std::vector< normal_type > &normals={}, const std::vector< index_type > &indexes={}, const std::vector< uv_type > &uvs={})
Definition: Mesh.h:57
This file contains definitions of common data structures used in traffic manager. ...
Definition: Carla.cpp:133
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
TArray< FVector > Normals
geom::Vector3D Vector3D
Definition: rpc/Vector3D.h:14
Material that references the vertex index start and end of a mesh where it is affecting.
Definition: Mesh.h:25
TArray< FVector > Vertices
std::vector< material_type > _materials
Definition: Mesh.h:243
Mesh data container, validator and exporter.
Definition: Mesh.h:44
std::array< int, 3 > Triangle
Definition: DataStructs.h:45
std::vector< index_type > _indexes
Definition: Mesh.h:239
std::vector< uv_type > _uvs
Definition: Mesh.h:241
geom::Vector2D Vector2D
Definition: rpc/Vector2D.h:14
std::vector< normal_type > _normals
Definition: Mesh.h:237
std::vector< vertex_type > _vertices
Definition: Mesh.h:235