1 #include "mesh.h"
2 
3 #include <iostream>
4 #include <fstream>
5 #include <sys/types.h>
6 
7 //#include "fs.h"
8 #include "geom.h"
9 #include "text.h"
10 #include "vertexLayout.h"
11 
12 //#include "tinyobjloader/tiny_obj_loader.h"
13 
Mesh()14 Mesh::Mesh():m_drawMode(GL_TRIANGLES) {
15 
16 }
17 
Mesh(const Mesh & _mother)18 Mesh::Mesh(const Mesh &_mother):m_drawMode(_mother.getDrawMode()) {
19     add(_mother);
20 }
21 
~Mesh()22 Mesh::~Mesh(){
23 
24 }
25 
setDrawMode(GLenum _drawMode)26 void Mesh::setDrawMode(GLenum _drawMode) {
27     m_drawMode = _drawMode;
28 }
29 
setColor(const glm::vec4 & _color)30 void Mesh::setColor(const glm::vec4 &_color) {
31     m_colors.clear();
32     for (unsigned int i = 0; i < m_vertices.size(); i++) {
33         m_colors.push_back(_color);
34     }
35 }
36 
addColor(const glm::vec4 & _color)37 void Mesh::addColor(const glm::vec4 &_color) {
38     m_colors.push_back(_color);
39 }
40 
addColors(const std::vector<glm::vec4> & _colors)41 void Mesh::addColors(const std::vector<glm::vec4> &_colors) {
42     m_colors.insert(m_colors.end(), _colors.begin(), _colors.end());
43 }
44 
addVertex(const glm::vec3 & _point)45 void Mesh::addVertex(const glm::vec3 &_point){
46    m_vertices.push_back(_point);
47 }
48 
addVertices(const std::vector<glm::vec3> & _verts)49 void Mesh::addVertices(const std::vector<glm::vec3>& _verts){
50    m_vertices.insert(m_vertices.end(),_verts.begin(),_verts.end());
51 }
52 
addVertices(const glm::vec3 * verts,int amt)53 void Mesh::addVertices(const glm::vec3* verts, int amt){
54    m_vertices.insert(m_vertices.end(),verts,verts+amt);
55 }
56 
addNormal(const glm::vec3 & _normal)57 void Mesh::addNormal(const glm::vec3 &_normal){
58     m_normals.push_back(_normal);
59 }
60 
addNormals(const std::vector<glm::vec3> & _normals)61 void Mesh::addNormals(const std::vector<glm::vec3> &_normals ){
62     m_normals.insert(m_normals.end(), _normals.begin(), _normals.end());
63 }
64 
addTexCoord(const glm::vec2 & _uv)65 void Mesh::addTexCoord(const glm::vec2 &_uv){
66     m_texCoords.push_back(_uv);
67 }
68 
addTexCoords(const std::vector<glm::vec2> & _uvs)69 void Mesh::addTexCoords(const std::vector<glm::vec2> &_uvs){
70     m_texCoords.insert(m_texCoords.end(), _uvs.begin(), _uvs.end());
71 }
72 
addIndex(uint16_t _i)73 void Mesh::addIndex(uint16_t _i){
74     m_indices.push_back(_i);
75 }
76 
addIndices(const std::vector<uint16_t> & inds)77 void Mesh::addIndices(const std::vector<uint16_t>& inds){
78 	m_indices.insert(m_indices.end(),inds.begin(),inds.end());
79 }
80 
addIndices(const uint16_t * inds,int amt)81 void Mesh::addIndices(const uint16_t* inds, int amt){
82 	m_indices.insert(m_indices.end(),inds,inds+amt);
83 }
84 
addTriangle(uint16_t index1,uint16_t index2,uint16_t index3)85 void Mesh::addTriangle(uint16_t index1, uint16_t index2, uint16_t index3){
86     addIndex(index1);
87     addIndex(index2);
88     addIndex(index3);
89 }
90 
add(const Mesh & _mesh)91 void Mesh::add(const Mesh &_mesh){
92 
93     if(_mesh.getDrawMode() != m_drawMode){
94         std::cout << "INCOMPATIBLE DRAW MODES" << std::endl;
95         return;
96     }
97 
98     uint16_t indexOffset = (uint16_t)getVertices().size();
99 
100     addColors(_mesh.getColors());
101     addVertices(_mesh.getVertices());
102     addNormals(_mesh.getNormals());
103     addTexCoords(_mesh.getTexCoords());
104 
105     for (unsigned int i = 0; i < _mesh.getIndices().size(); i++) {
106         addIndex(indexOffset+_mesh.getIndices()[i]);
107     }
108 }
109 
getDrawMode() const110 GLenum Mesh::getDrawMode() const{
111     return m_drawMode;
112 }
113 
getColors() const114 const std::vector<glm::vec4> & Mesh::getColors() const{
115     return m_colors;
116 }
117 
getVertices() const118 const std::vector<glm::vec3> & Mesh::getVertices() const{
119 	return m_vertices;
120 }
121 
getNormals() const122 const std::vector<glm::vec3> & Mesh::getNormals() const{
123     return m_normals;
124 }
125 
getTexCoords() const126 const std::vector<glm::vec2> & Mesh::getTexCoords() const{
127     return m_texCoords;
128 }
129 
getIndices() const130 const std::vector<uint16_t> & Mesh::getIndices() const{
131     return m_indices;
132 }
133 
getTriangles() const134 std::vector<glm::ivec3> Mesh::getTriangles() const {
135     std::vector<glm::ivec3> faces;
136 
137     if(getDrawMode() == GL_TRIANGLES) {
138         if(m_indices.size()>0){
139             for(unsigned int j = 0; j < m_indices.size(); j += 3) {
140                 glm::ivec3 tri;
141                 for(int k = 0; k < 3; k++) {
142                     tri[k] = m_indices[j+k];
143                 }
144                 faces.push_back(tri);
145             }
146         } else {
147             for( unsigned int j = 0; j < m_vertices.size(); j += 3) {
148                 glm::ivec3 tri;
149                 for(int k = 0; k < 3; k++) {
150                     tri[k] = j+k;
151                 }
152                 faces.push_back(tri);
153             }
154         }
155     } else {
156         //  TODO
157         //
158         std::cout << "ERROR: Mesh only add GL_TRIANGLES for NOW !!" << std::endl;
159     }
160 
161     return faces;
162 }
163 
clear()164 void Mesh::clear(){
165     if(!m_vertices.empty()){
166 		m_vertices.clear();
167 	}
168 	if(!m_colors.empty()){
169 		m_colors.clear();
170 	}
171 	if(!m_normals.empty()){
172 		m_normals.clear();
173 	}
174     if(!m_indices.empty()){
175 		m_indices.clear();
176 	}
177 }
178 
computeNormals()179 void Mesh::computeNormals(){
180 
181     if(getDrawMode() == GL_TRIANGLES){
182         //The number of the vertices
183         int nV = m_vertices.size();
184 
185         //The number of the triangles
186         int nT = m_indices.size() / 3;
187 
188         std::vector<glm::vec3> norm( nV ); //Array for the normals
189 
190         //Scan all the triangles. For each triangle add its
191         //normal to norm's vectors of triangle's vertices
192         for (int t=0; t<nT; t++) {
193 
194             //Get indices of the triangle t
195             int i1 = m_indices[ 3 * t ];
196             int i2 = m_indices[ 3 * t + 1 ];
197             int i3 = m_indices[ 3 * t + 2 ];
198 
199             //Get vertices of the triangle
200             const glm::vec3 &v1 = m_vertices[ i1 ];
201             const glm::vec3 &v2 = m_vertices[ i2 ];
202             const glm::vec3 &v3 = m_vertices[ i3 ];
203 
204             //Compute the triangle's normal
205             glm::vec3 dir = glm::normalize(glm::cross(v2-v1,v3-v1));
206 
207             //Accumulate it to norm array for i1, i2, i3
208             norm[ i1 ] += dir;
209             norm[ i2 ] += dir;
210             norm[ i3 ] += dir;
211         }
212 
213         //Normalize the normal's length and add it.
214         m_normals.clear();
215         for (int i=0; i<nV; i++) {
216             addNormal( glm::normalize(norm[i]) );
217         }
218 
219     } else {
220         //  TODO
221         //
222         std::cout << "ERROR: Mesh only add GL_TRIANGLES for NOW !!" << std::endl;
223     }
224 }
225 
getVbo()226 Vbo* Mesh::getVbo() {
227 
228     // Create Vertex Layout
229     //
230     std::vector<VertexLayout::VertexAttrib> attribs;
231     attribs.push_back({"position", 3, GL_FLOAT, POSITION_ATTRIBUTE, false, 0});
232     int  nBits = 3;
233 
234     bool bColor = false;
235     if (getColors().size() > 0 && getColors().size() == m_vertices.size()){
236         attribs.push_back({"color", 4, GL_FLOAT, COLOR_ATTRIBUTE, false, 0});
237         bColor = true;
238         nBits += 4;
239     }
240 
241     bool bNormals = false;
242     if (getNormals().size() > 0 && getNormals().size() == m_vertices.size()){
243         attribs.push_back({"normal", 3, GL_FLOAT, NORMAL_ATTRIBUTE, false, 0});
244         bNormals = true;
245         nBits += 3;
246     }
247 
248     bool bTexCoords = false;
249     if (getTexCoords().size() > 0 && getTexCoords().size() == m_vertices.size()){
250         attribs.push_back({"texcoord", 2, GL_FLOAT, TEXCOORD_ATTRIBUTE, false, 0});
251         bTexCoords = true;
252         nBits += 2;
253     }
254 
255     VertexLayout* vertexLayout = new VertexLayout(attribs);
256     Vbo* tmpMesh = new Vbo(vertexLayout);
257     tmpMesh->setDrawMode(getDrawMode());
258 
259     std::vector<GLfloat> data;
260     for(unsigned int i = 0; i < m_vertices.size(); i++){
261         data.push_back(m_vertices[i].x);
262         data.push_back(m_vertices[i].y);
263         data.push_back(m_vertices[i].z);
264         if(bColor){
265             data.push_back(m_colors[i].r);
266             data.push_back(m_colors[i].g);
267             data.push_back(m_colors[i].b);
268             data.push_back(m_colors[i].a);
269         }
270         if(bNormals){
271             data.push_back(m_normals[i].x);
272             data.push_back(m_normals[i].y);
273             data.push_back(m_normals[i].z);
274         }
275         if(bTexCoords){
276             data.push_back(m_texCoords[i].x);
277             data.push_back(m_texCoords[i].y);
278         }
279     }
280 
281     tmpMesh->addVertices((GLbyte*)data.data(), m_vertices.size());
282 
283     if(getIndices().size()==0){
284         if ( getDrawMode() == GL_LINES ) {
285             for (unsigned int i = 0; i < getVertices().size(); i++){
286                 addIndex(i);
287             }
288         } else if ( getDrawMode() == GL_LINE_STRIP ) {
289             for (unsigned int i = 1; i < getVertices().size(); i++){
290                 addIndex(i-1);
291                 addIndex(i);
292             }
293         }
294     }
295 
296     tmpMesh->addIndices(m_indices.data(), m_indices.size());
297 
298     return tmpMesh;
299 }
300