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