23 std::cout <<
"Mesh validation error: there are no vertices in the mesh." << std::endl;
29 std::cout <<
"Mesh validation error: the index amount must be multiple of 3." << std::endl;
34 std::cout <<
"Mesh validation error: last material was not closed." << std::endl;
48 if (vertices.size() == 0) {
54 bool index_clockwise =
true;
56 index_clockwise = !index_clockwise;
57 if (index_clockwise) {
94 std::copy(vertices.begin(), vertices.end(), std::back_inserter(
_vertices));
110 std::copy(uv.begin(), uv.end(), std::back_inserter(
_uvs));
114 const size_t open_index =
_indexes.size();
122 if (open_index % 3 != 0) {
123 std::cout <<
"open_index % 3 != 0" << std::endl;
126 _materials.emplace_back(material_name, open_index, 0);
130 const size_t close_index =
_indexes.size();
132 _materials.back().index_start == close_index ||
138 if (
_indexes.empty() || close_index % 3 != 0) {
150 std::stringstream out;
153 out <<
"# List of geometric vertices, with (x, y, z) coordinates." << std::endl;
155 out <<
"v " << v.x <<
" " << v.y <<
" " << v.z << std::endl;
159 out << std::endl <<
"# List of texture coordinates, in (u, v) coordinates, these will vary between 0 and 1." << std::endl;
160 for (
auto &vt :
_uvs) {
161 out <<
"vt " << vt.x <<
" " << vt.y << std::endl;
166 out << std::endl <<
"# List of vertex normals in (x, y, z) form; normals might not be unit vectors." << std::endl;
168 out <<
"vn " << vn.x <<
" " << vn.y <<
" " << vn.z << std::endl;
173 out << std::endl <<
"# Polygonal face element." << std::endl;
176 size_t index_counter = 0u;
181 if (it_m->index_end == index_counter) {
185 if (it_m->index_start == index_counter) {
186 out <<
"\nusemtl " << it_m->name << std::endl;
191 out <<
"f " << *it; ++it;
192 out <<
" " << *it; ++it;
193 out <<
" " << *it << std::endl; ++it;
206 std::stringstream out;
229 constexpr float MaxSaneCoordinate = 1e5f;
230 const auto is_sane_vertex = [](
const vertex_type &v) {
231 return std::fabs(v.x) <= MaxSaneCoordinate &&
232 std::fabs(v.y) <= MaxSaneCoordinate &&
233 std::fabs(v.z) <= MaxSaneCoordinate;
236 size_t sanitized_vertices = 0u;
237 out <<
"# List of geometric vertices, with (x, y, z) coordinates." << std::endl;
239 if (is_sane_vertex(v)) {
241 out <<
"v " << v.x <<
" " << v.z <<
" " << v.y << std::endl;
243 out <<
"v 0 0 0" << std::endl;
244 ++sanitized_vertices;
249 out << std::endl <<
"# Polygonal face element." << std::endl;
252 size_t index_counter = 0u;
253 size_t skipped_faces = 0u;
258 if (it_m->index_end == index_counter) {
262 if (it_m->index_start == index_counter) {
263 out <<
"\nusemtl " << it_m->name << std::endl;
267 const auto i_1 = *it; ++it;
268 const auto i_2 = *it; ++it;
269 const auto i_3 = *it; ++it;
273 if (i_1 == 0 || i_2 == 0 || i_3 == 0 ||
285 out <<
"f " << i_1 <<
" " << i_3 <<
" " << i_2 << std::endl;
287 if (skipped_faces > 0u) {
288 std::cout <<
"Mesh::GenerateOBJForRecast: sanitized " << sanitized_vertices
289 <<
" out-of-range vertex/vertices and skipped " << skipped_faces
290 <<
" face(s) referencing them (beyond "
291 << MaxSaneCoordinate <<
"m from the origin)." << std::endl;
300 return "Invalid Mesh";
303 std::stringstream out;
364 const size_t vertices_to_link =
static_cast<size_t>(num_vertices_to_link);
365 const size_t vertex_to_start_concating = v_num - vertices_to_link;
366 for(
size_t i = 1; i < vertices_to_link; ++i ) {
367 _indexes.push_back( vertex_to_start_concating + i );
368 _indexes.push_back( vertex_to_start_concating + i + 1 );
371 _indexes.push_back( vertex_to_start_concating + i + 1);
380 [=](
size_t index) {return index + v_num; });
392 mat.index_start += i_num;
393 mat.index_end += i_num;
418 [=](
size_t index) {return index + v_num;});
430 mat.index_start += i_num;
431 mat.index_end += i_num;
#define DEBUG_ASSERT(predicate)
Mesh data container, validator and exporter.
void AddIndex(index_type index)
Appends a index to the indexes list.
void AddVertex(vertex_type vertex)
Appends a vertex to the vertices list.
std::vector< vertex_type > _vertices
void AddVertices(const std::vector< vertex_type > &vertices)
Appends a vertex to the vertices list.
std::string GenerateOBJ() const
Returns a string containing the mesh encoded in OBJ.
void AddUV(uv_type uv)
Appends a vertex to the vertices list, they will be read 3 in 3.
Mesh & ConcatMesh(const Mesh &rhs, int num_vertices_to_link)
Merges two meshes into a single mesh.
std::vector< index_type > _indexes
const std::vector< uv_type > & GetUVs() const
const std::vector< index_type > & GetIndexes() const
std::string GeneratePLY() const
Returns a string containing the mesh encoded in PLY.
bool IsValid() const
Check if the mesh can be valid or not.
void AddUVs(const std::vector< uv_type > &uv)
Appends uvs.
std::string GenerateOBJForRecast() const
Returns a string containing the mesh encoded in OBJ.
size_t GetVerticesNum() const
void AddNormal(normal_type normal)
Appends a normal to the normal list.
std::vector< normal_type > _normals
std::vector< material_type > _materials
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.
Mesh & operator+=(const Mesh &rhs)
Merges two meshes into a single mesh.
const std::vector< material_type > & GetMaterials() const
const std::vector< normal_type > & GetNormals() const
size_t GetLastVertexIndex() const
Returns the index of the last added vertex (number of vertices).
void AddTriangleFan(const std::vector< vertex_type > &vertices)
Adds a triangle fan to the mesh, vertex order is counterclockwise.
std::vector< uv_type > _uvs
size_t GetIndexesNum() const
void AddTriangleStrip(const std::vector< vertex_type > &vertices)
Adds a triangle strip to the mesh, vertex order is counterclockwise.
const std::vector< vertex_type > & GetVertices() const
Mesh operator+(const Mesh &lhs, const Mesh &rhs)
This file contains definitions of common data structures used in traffic manager.
Material that references the vertex index start and end of a mesh where it is affecting.