gKit2 light
Loading...
Searching...
No Matches
mesh_buffer.cpp
Go to the documentation of this file.
1
2
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
12struct compareMaterial
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
26struct 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
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}
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.
representation d'un objet openGL.
representation des donnees d'un fichier wavefront .obj
representation d'un objet.
Definition mesh_buffer.h:22
std::vector< MaterialData > materials
ensemble de matieres
Definition mesh_buffer.h:30
representation d'une sequence de triangles associes a la meme matiere
Definition mesh_buffer.h:11
representation de l'indexation complete d'un sommet
vecteur generique, utilitaire.
Definition vec.h:152
vecteur generique, utilitaire.
Definition vec.h:169
representation de l'indexation complete d'un sommet
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...