gKit2 light
mesh_buffer.cpp
Go to the documentation of this file.
1 
3 #include <cassert>
4 #include <map>
5 #include <algorithm>
6 
7 #include "mesh_data.h"
8 #include "mesh_buffer.h"
9 
10 
11 // compare la matiere de 2 triangles
13 {
14  const std::vector<int>& material_buffer;
15 
16  compareMaterial( const std::vector<int>& _buffer ) : material_buffer(_buffer) {}
17 
18  bool operator() ( const int& a, const int& b ) const
19  {
20  return material_buffer[a] < material_buffer[b];
21  }
22 };
23 
24 
26 struct MeshVertex
27 {
28  int material;
29  int position;
30  int texcoord;
31  int normal;
32 
33  MeshVertex( ) : material(-1), position(-1), texcoord(-1), normal(-1) {}
34  MeshVertex( const int m, const int p, const int t, const int n ) : material(m), position(p), texcoord(t), normal(n) {}
35 
36  // comparaison lexicographique de 2 indices
37  bool operator< ( const MeshVertex& b ) const
38  {
39  if(material != b.material) return material < b.material;
40  if(position != b.position) return position < b.position;
41  if(texcoord != b.texcoord) return texcoord < b.texcoord;
42  if(normal != b.normal) return normal < b.normal;
43  return false;
44  }
45 };
46 
47 
48 MeshBuffer buffers( const MeshData& data )
49 {
50  MeshBuffer mesh;
51 
52  mesh.materials= data.materials;
53  mesh.material_indices.reserve(data.material_indices.size());
54 
55  mesh.positions.reserve(data.positions.size());
56  mesh.texcoords.reserve(data.positions.size());
57  mesh.normals.reserve(data.positions.size());
58 
59  // tri les triangles par matiere
60  std::vector<int> triangles;
61  triangles.reserve(data.material_indices.size());
62  for(int i= 0; i < (int) data.material_indices.size(); i++)
63  triangles.push_back(i);
64 
65  std::sort(triangles.begin(), triangles.end(), compareMaterial(data.material_indices));
66 
67  // groupes de triangles
68  int material_id= data.material_indices[triangles[0]];
69  mesh.material_groups.push_back( MeshGroup(material_id, 0) );
70 
71  bool has_texcoords= !data.texcoords.empty();
72  bool has_normals= !data.normals.empty();
73 
74  // re ordonne les triangles et les attributs
75  std::map<MeshVertex, int> remap;
76  for(int i= 0; i < (int) triangles.size(); i++)
77  {
78  // matiere du triangle
79  mesh.material_indices.push_back(data.material_indices[triangles[i]]);
80 
81  // associe la matiere de la face a ses sommets
82  if(material_id != data.material_indices[triangles[i]])
83  {
84  // construit les groupes de triangles associes a la meme matiere
85  material_id= data.material_indices[triangles[i]];
86 
87  mesh.material_groups.back().count= 3*i - mesh.material_groups.back().first;
88  mesh.material_groups.push_back( MeshGroup(material_id, 3*i) );
89  }
90 
91  for(int k= 0; k < 3; k++)
92  {
93  // indice du kieme sommet du ieme triangle re-ordonne
94  int index= 3*triangles[i] + k;
95  MeshVertex vertex= MeshVertex(material_id, data.position_indices[index], data.texcoord_indices[index], data.normal_indices[index]);
96 
97  auto found= remap.insert( std::make_pair(vertex, remap.size()) );
98  if(found.second)
99  {
100  // copie les attributs
101  assert(data.position_indices[index] != -1);
102  mesh.positions.push_back( data.positions[data.position_indices[index]] );
103 
104  if(data.texcoord_indices[index] != -1)
105  // copie les texcoord du sommet, si elles sont definies
106  mesh.texcoords.push_back( data.texcoords[data.texcoord_indices[index]] );
107  else if(has_texcoords)
108  // copie une valeur par defaut, tous les sommets n'ont pas de texcoord
109  mesh.texcoords.push_back( vec2() );
110 
111  if(data.normal_indices[index] != -1)
112  // copie la normale du sommet, si ell est definie
113  mesh.normals.push_back( data.normals[data.normal_indices[index]] );
114  else if(has_normals)
115  // copie une valeur par defaut, tous les sommets n'ont pas de normale
116  mesh.normals.push_back( vec3() );
117  }
118 
119  // construit l'index buffer
120  mesh.indices.push_back(found.first->second);
121  }
122  }
123 
124  // termine la description du dernier groupe de triangles
125  mesh.material_groups.back().count= 3*triangles.size() - mesh.material_groups.back().first;
126 
127  printf("buffers : %d positions, %d texcoords, %d normals, %d indices, %d groups\n",
128  (int) mesh.positions.size(), (int) mesh.texcoords.size(), (int) mesh.normals.size(), (int) mesh.indices.size(), (int) mesh.material_groups.size());
129 
130  return mesh;
131 }
const std::vector< unsigned int > & material_indices() const
renvoie les indices des matieres des triangles.
Definition: mesh.cpp:287
const Materials & materials() const
renvoie la description des matieres.
Definition: mesh.cpp:267
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition: text.cpp:140
MeshBuffer buffers(const MeshData &data)
construction a partir des donnees d'un maillage.
Definition: mesh_buffer.cpp:48
representation d'un objet openGL.
representation des donnees d'un fichier wavefront .obj
representation d'un objet.
Definition: mesh_buffer.h:22
representation d'une sequence de triangles associes a la meme matiere
Definition: mesh_buffer.h:11
representation de l'indexation complete d'un sommet
Definition: mesh_buffer.cpp:27
vecteur generique, utilitaire.
Definition: vec.h:131
vecteur generique, utilitaire.
Definition: vec.h:146
representation de l'indexation complete d'un sommet
Definition: wavefront.cpp:176
bool has_normals(const Hit &hit, const GLTFScene &scene)
verifie la presence des normales par sommet.
bool has_texcoords(const Hit &hit, const GLTFScene &scene)
verifie la presence des coordonnees de texture...