Computational Embodied Neuroscience Simulator  1.1
3D simulation library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
cens_graphics_shape.cpp
Go to the documentation of this file.
1 // Computational Embodied Neuroscience Simulator (CENS) Library
2 // Copyright (c) 2010 Francesco Mannella
3 //
4 // cens_graphics_shape.cpp
5 // Copyright (c) 2010 Francesco Mannella
6 //
7 // This file is part of CENS library.
8 //
9 // CENS library is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // CENS library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with CENS library. If not, see <http://www.gnu.org/licenses/>.
21 
22 #include "cens_graphics_shape.h"
23 #include "cens_types.h"
24 
25 namespace cens
26 {
27 
28  Vector3f GS_NULL_COLOR = Vector3f(-1,-1,-1);
29 
30 
32 
33  void CENSGraphicsShape::copyimage(const GLubyte *source)
34  {
35 
37  delete[] m_gsTextureImage;
38 
39  if(source==0)
40  {
41 
42  m_gsTextureWidth = 256;
43  m_gsTextureHeight = 256;
44  m_gsTextureImage = new GLubyte[256*256*3];
45  for(int y=0;y<256;++y)
46  {
47  const int t=y>>4;
48  GLubyte*pi=m_gsTextureImage+y*256*3;
49  for(int x=0;x<256;++x)
50  {
51  const int s=x>>4;
52  const GLubyte b=180;
53  GLubyte c = b+(((s+t)&1)&1)*(255-b);
54  pi[0]=pi[1]=pi[2]=c;pi+=3;
55  }
56  }
57 
58  } else
59  {
60 
62  for(int x=0;x<m_gsTextureWidth*m_gsTextureHeight*3; x++)
63  {
64  m_gsTextureImage[x] = source[x];
65  }
66 
67  }
68 
69  }
70 
71 
73 
75  {
76 
78  delete[] m_gsTextureImage;
79 
80  }
81 
83  // BUILDS //////////////////////////////////////////////////////////////////////
85 
86  void CENSGraphicsShape::buildAsPlane(const Vector3f &orig, const Vector3f &v1,
87  const Vector3f &v2, const Vector3f &color, CENSPixelMap texture)
88  {
89 
91  m_gsColor=color;
92  m_gsTextureWidth = texture.getWidth();
93  m_gsTextureHeight = texture.getHeight();
94  copyimage(texture.getData());
95  addVertex(orig);
96  addVertex(v1);
97  addVertex(v2);
98  }
99 
101 
102  void CENSGraphicsShape::buildAsBox(const Vector3f &halfExtents,
103  const Vector3f &color, CENSPixelMap texture)
104  {
105 
106  m_gsType = GS_BOX;
107  m_gsColor=color;
108  m_gsTextureWidth = texture.getWidth();
109  m_gsTextureHeight = texture.getHeight();
110  copyimage(texture.getData());
111  // triples of texture coordinates for each triangle
112 
113  static int tex_coords[12][6] =
114  {
115  {1,1,0,1,1,0},
116  {0,0,1,0,0,1},
117  {1,1,0,1,1,0},
118  {1,0,0,1,0,0},
119  {1,1,0,1,1,0},
120  {1,0,0,1,0,0},
121  {1,1,0,1,0,0},
122  {0,0,1,1,1,0},
123  {1,0,1,1,0,0},
124  {0,0,1,1,1,0},
125  {1,0,0,1,0,0},
126  {0,1,1,1,1,0} };
127 
128 
129  // defining half extents
130 
131  Vector3f dx(1,0,0);
132  Vector3f dy(0,1,0);
133  Vector3f dz(0,0,1);
134 
135  dx *= halfExtents[0];
136  dy *= halfExtents[1];
137  dz *= halfExtents[2];
138 
139  // defining vertices coordinates
140 
141  Vertices vertices;
142  vertices.push_back( dx+dy+dz);
143  vertices.push_back(-dx+dy+dz);
144  vertices.push_back( dx-dy+dz);
145  vertices.push_back(-dx-dy+dz);
146  vertices.push_back( dx+dy-dz);
147  vertices.push_back(-dx+dy-dz);
148  vertices.push_back( dx-dy-dz);
149  vertices.push_back(-dx-dy-dz);
150 
151  setVertices(vertices);
152 
153  for(int x=0; x<12; x++)
154  {
155  addTexCoord(Vector2f(
156  tex_coords[x][0],
157  tex_coords[x][1] ));
158  addTexCoord(Vector2f(
159  tex_coords[x][2],
160  tex_coords[x][3] ));
161  addTexCoord(Vector2f(
162  tex_coords[x][4],
163  tex_coords[x][5] ));
164  }
165 
166  }
167 
169 
171  const Vector3f &color, CENSPixelMap texture)
172  {
173 
175  m_gsColor=color;
176  m_gsTextureWidth = texture.getWidth();
177  m_gsTextureHeight = texture.getHeight();
178  copyimage(texture.getData());
179 
180  float xtag = 1/(float)GS_SPHERE_LATS;
181  float ytag = 1/(float)GS_SPHERE_LONGS;
182 
183  for(int i = 0; i <= GS_SPHERE_LATS; i++)
184  {
185 
186  float lat0 = M_PI * (-float(0.5) + (i - 1) * xtag);
187  float z0 = radius*sin(lat0);
188  float zr0 = radius*cos(lat0);
189 
190  float lat1 = M_PI * (-float(0.5) + i * xtag);
191  float z1 = radius*sin(lat1);
192  float zr1 = radius*cos(lat1);
193 
194  for(int j = 0; j <= GS_SPHERE_LONGS; j++)
195  {
196 
197  float lng = 2 * M_PI * (j - 1) * ytag;
198  float x = cos(lng);
199  float y = sin(lng);
200 
201  Vector3f ver1(x * zr1, y * zr1, z1);
202  Vector3f ver2(x * zr0, y * zr0, z0);
203 
204  addTexCoord(Vector2f(xtag*i, ytag*j));
205  addTexCoord(Vector2f(xtag*(i-1), ytag*j));
206  addVertex(ver1);
207  addVertex(ver2);
208  }
209  }
210 
211  }
212 
214 
216  const Vertices &vtx,
217  const unsigned int *idx,
218  int nvtxs, int nidxs, int ntrns,
219  const TexCoords &texCoords,
220  const Vector3f &color,
221  CENSPixelMap texture)
222  {
223 
225  m_gsColor=color;
226  m_gsTextureWidth = texture.getWidth();
227  m_gsTextureHeight = texture.getHeight();
228  copyimage(texture.getData());
229 
230  if (ntrns > 0)
231  {
232  int index = 0;
233 
234  for (int i = 0; i < ntrns; i++)
235  {
236 
237  int i1 = index++;
238  int i2 = index++;
239  int i3 = index++;
240 
241  assert(i1 < nidxs &&
242  i2 < nidxs
243  && i3 < nidxs);
244 
245  int index1 = idx[i1];
246  int index2 = idx[i2];
247  int index3 = idx[i3];
248  assert(index1 < nvtxs &&
249  index2 < nvtxs &&
250  index3 < nvtxs );
251 
252  Vector3f v1 = vtx[index1];
253  Vector3f v2 = vtx[index2];
254  Vector3f v3 = vtx[index3];
255 
256  Vector3f axis = (v3-v1).cross(v2-v1);
257  axis.normalize ();
258 
259  m_gsVertices.push_back(v1);
260  m_gsVertices.push_back(v2);
261  m_gsVertices.push_back(v3);
262 
263  if(texCoords.size()==0)
264  {
265  float div = 10.;
266 
267  m_gsTexCoords.push_back(Vector2f(
268  v1.x()/div, v1.z()/div ));
269  m_gsTexCoords.push_back(Vector2f(
270  v2.x()/div, v2.z()/div ));
271  m_gsTexCoords.push_back(Vector2f(
272  v3.x()/div, v3.z()/div ));
273  }
274  }
275 
276  if(texCoords.size()!=0)
277  {
278  setTexCoords(texCoords);
279  }
280  }
281  }
283 
285  int numTriangles,
286  const TexCoords &texCoords,
287  const Vector3f &color,
288  CENSPixelMap texture)
289  {
290 
291  m_gsType = GS_SOFT;
292  m_gsColor=color;
293  m_gsTextureWidth = texture.getWidth();
294  m_gsTextureHeight = texture.getHeight();
295  copyimage(texture.getData());
296 
297  m_gsVertices.resize(numTriangles*3);
298  m_gsNormals.resize(numTriangles);
299 
300  if(texCoords.size()!=0)
301  {
302  setTexCoords(texCoords);
303  }
304 
305  }
306 
308  // DRAW ////////////////////////////////////////////////////////////////////////
310 
311 
312  void CENSGraphicsShape::draw(const Vector3f &org, const Matrix3f &rot)
313  {
314  static int indices[12][3] =
315  {
316  {0,1,2},
317  {3,2,1},
318  {4,0,6},
319  {6,0,2},
320  {5,1,4},
321  {4,1,0},
322  {7,3,1},
323  {7,1,5},
324  {5,4,7},
325  {7,4,6},
326  {7,2,3},
327  {7,6,2} };
328 
329  Vector3f v1 = Vector3f(0,0,0);
330  Vector3f v2 = Vector3f(0,0,0);
331  Vector3f v3 = Vector3f(0,0,0);
332  Vector3f normal = Vector3f(0,0,0);
333 
334  Vector2f t1 = Vector2f(0,0);
335  Vector2f t2 = Vector2f(0,0);
336  Vector2f t3 = Vector2f(0,0);
337 
338  setTexture();
339 
340  glColor3f(m_gsColor[0],m_gsColor[1],m_gsColor[2]);
341 
342  switch(m_gsType)
343  {
344  case GS_PLANE:
345  {
346  glPushMatrix();
347 
348  float vecLen = 20.f;
349  Vector3f pt0 = m_gsVertices[0] + m_gsVertices[1]*vecLen;
350  Vector3f pt1 = m_gsVertices[0] - m_gsVertices[1]*vecLen;
351  Vector3f pt2 = m_gsVertices[0] + m_gsVertices[2]*vecLen;
352  Vector3f pt3 = m_gsVertices[0] - m_gsVertices[2]*vecLen;
353 
354  glBegin(GL_QUADS);
355 
356  glVertex3f(pt0.x(),pt0.y(),pt0.z());
357  glVertex3f(pt2.x(),pt2.y(),pt2.z());
358  glVertex3f(pt1.x(),pt1.y(),pt1.z());
359  glVertex3f(pt3.x(),pt3.y(),pt3.z());
360 
361  glEnd();
362 
363  glPopMatrix();
364  }
365  break;
366  case GS_BOX:
367  {
368 
369  glPushMatrix();
370 
371  glBegin(GL_TRIANGLES);
372 
373  int si=12;
374  for (int i=0;i<si;i++)
375  {
376 
377  v1 = org + rot*m_gsVertices[indices[i][0]];
378  v2 = org + rot*m_gsVertices[indices[i][1]];
379  v3 = org + rot*m_gsVertices[indices[i][2]];
380 
381  t1 = m_gsTexCoords[i*3 + 0];
382  t2 = m_gsTexCoords[i*3 + 1];
383  t3 = m_gsTexCoords[i*3 + 2];
384 
385  // enable reflection on the triangle
386 
387  Vector3f normal = (v3-v1).cross(v2-v1);
388  normal.normalize ();
389  glNormal3f(normal.x(),normal.y(),normal.z());
390 
391  // draws a triangle
392 
393  glTexCoord2f(t1[0],t1[1]);
394  glVertex3f (v1.x(), v1.y(), v1.z());
395  glTexCoord2f(t2[0],t2[1]);
396  glVertex3f (v2.x(), v2.y(), v2.z());
397  glTexCoord2f(t3[0],t3[1]);
398  glVertex3f (v3.x(), v3.y(), v3.z());
399 
400  }
401  glEnd();
402 
403  glPopMatrix();
404  }
405  break;
406  case GS_SPHERE :
407  {
408  glPushMatrix();
409 
410  for(int i = 0; i <= (GS_SPHERE_LATS + 1); i++)
411  {
412  glBegin(GL_QUAD_STRIP);
413  for(int j = 0; j <= (GS_SPHERE_LONGS*2); j+=2)
414  {
415 
416  v1 = org + rot*m_gsVertices[ i*GS_SPHERE_LONGS*2 + j ];
417  v2 = org + rot*m_gsVertices[ i*GS_SPHERE_LONGS*2 + j + 1 ];
418  t1 = m_gsTexCoords[ i*GS_SPHERE_LONGS*2 + j ];
419  t2 = m_gsTexCoords[ i*GS_SPHERE_LONGS*2 + j + 1 ];
420 
421  glNormal3f(v1.x(),v1.y(),v1.z());
422  glTexCoord2f(t1[0],t1[1]);
423  glVertex3f(v1.x(),v1.y(),v1.z());
424 
425  glNormal3f(v2.x(),v2.y(),v2.z());
426  glTexCoord2f(t2[0],t2[1]);
427  glVertex3f(v2.x(),v2.y(),v2.z());
428 
429  }
430  glEnd();
431  }
432  glPopMatrix();
433  }
434  break;
435  case GS_CONVEX:
436  {
437 
438  glPushMatrix();
439 
440  glBegin(GL_TRIANGLES);
441 
442  Vector3f v1;
443  Vector3f v2;
444  Vector3f v3;
445  Vector3f normal;
446  Vector2f t1;
447  Vector2f t2;
448  Vector2f t3;
449 
450  for (unsigned int i = 0; i < m_gsVertices.size()/3; i++)
451  {
452 
453  v1 = org + rot*m_gsVertices[i*3 + 0];
454  v2 = org + rot*m_gsVertices[i*3 + 1];
455  v3 = org + rot*m_gsVertices[i*3 + 2];
456  normal = (v3-v1).cross(v2-v1);
457  normal.normalize ();
458  t1 = m_gsTexCoords[i*3 + 0];
459  t2 = m_gsTexCoords[i*3 + 1];
460  t3 = m_gsTexCoords[i*3 + 2];
461 
462  glNormal3f(normal.x(),normal.y(),normal.z());
463  glTexCoord2f(t1[0],t1[1]);
464  glVertex3f (v1.x(), v1.y(), v1.z());
465  glTexCoord2f(t2[0],t2[1]);
466  glVertex3f (v2.x(), v2.y(), v2.z());
467  glTexCoord2f(t3[0],t3[1]);
468  glVertex3f (v3.x(), v3.y(), v3.z());
469 
470  }
471  glEnd();
472 
473  glPopMatrix();
474 
475  }
476  default:
477  break;
478  }
479  }
480 
482 
484  {
485 
486  Vector3f v1 = Vector3f(0,0,0);
487  Vector3f v2 = Vector3f(0,0,0);
488  Vector3f v3 = Vector3f(0,0,0);
489  Vector3f n1 = Vector3f(0,0,0);
490  Vector2f t1;
491  Vector2f t2;
492  Vector2f t3;
493 
494  setTexture();
495 
496  glColor3f(m_gsColor[0],m_gsColor[1],m_gsColor[2]);
497 
498  glPushMatrix();
499 
500  glBegin(GL_TRIANGLES);
501 
502  bool texture = m_gsTexCoords.size()!=0;
503 
504  for(unsigned int n=0; n<m_gsVertices.size()/3; n++)
505  {
506 
507  v1 = m_gsVertices[n*3 + 0];
508  v2 = m_gsVertices[n*3 + 1];
509  v3 = m_gsVertices[n*3 + 2];
510  n1 = m_gsNormals[n];
511  if(texture) {
512  t1 = m_gsTexCoords[n*3 + 0];
513  t2 = m_gsTexCoords[n*3 + 1];
514  t3 = m_gsTexCoords[n*3 + 2];
515  }
516  // enable reflection on the triangle
517 
518  glNormal3f(n1.x(),n1.y(),n1.z());
519 
520  // draws a triangle
521 
522  if(texture) glTexCoord2f(t1[0],t1[1]);
523  glVertex3f (v1.x(), v1.y(), v1.z());
524  if(texture) glTexCoord2f(t2[0],t2[1]);
525  glVertex3f (v2.x(), v2.y(), v2.z());
526  if(texture) glTexCoord2f(t3[0],t3[1]);
527  glVertex3f (v3.x(), v3.y(), v3.z());
528 
529  }
530 
531  glEnd();
532 
533  glPopMatrix();
534 
535  }
536 
538 
540  {
541 
542  glBindTexture( GL_TEXTURE_2D, m_gsTexture );
543 
544  }
545 
547 
549  {
550 
551  // texture init
552  glGenTextures( 1, &m_gsTexture );
553  glBindTexture( GL_TEXTURE_2D, m_gsTexture );
554 
555  if(m_gsTextureImage)
556  gluBuild2DMipmaps(
557  GL_TEXTURE_2D,3,m_gsTextureWidth,m_gsTextureHeight,
558  GL_RGB,GL_UNSIGNED_BYTE,
560 
561  glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
562  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
563  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
564  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
565  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
566 
567 
568  glBindTexture( GL_TEXTURE_2D, 0 );
569 
570  }
571 
572 
574  // GETS ////////////////////////////////////////////////////////////////////////
576 
578  {
579  return m_gsType;
580  }
581 
583 
584  const Vector3f &CENSGraphicsShape::getColor()
585  {
586  return m_gsColor;
587  }
588 
589 
591 
593  {
594  return m_gsVertices;
595  }
596 
598 
599  Vector3f& CENSGraphicsShape::getVertex(int vertex_index)
600  {
601  return m_gsVertices[vertex_index];
602  }
603 
605 
607  {
608  return m_gsNormals;
609  }
610 
612 
613  Vector3f& CENSGraphicsShape::getNormal(int vertex_index)
614  {
615  return m_gsNormals[vertex_index];
616  }
617 
619 
621  {
622  return m_gsTexCoords;
623  }
624 
626 
627  Vector2f& CENSGraphicsShape::getTexCoord(int texcoord_index)
628  {
629  return m_gsTexCoords[texcoord_index];
630  }
631 
633  // SETS ////////////////////////////////////////////////////////////////////////
635 
637  {
638  m_gsType = type;
639  }
640 
642 
643  void CENSGraphicsShape::setColor(const Vector3f &color)
644  {
645  m_gsColor = color;
646  }
647 
649 
651  {
652  m_gsVertices = vertices;
653  }
654 
656 
657  void CENSGraphicsShape::addVertex(const Vector3f &vertex)
658  {
659  m_gsVertices.push_back(vertex);
660  }
661 
663 
665  {
666  m_gsNormals = vertices;
667  }
668 
670 
671  void CENSGraphicsShape::addNormal(const Vector3f &vertex)
672  {
673  m_gsNormals.push_back(vertex);
674  }
675 
677 
679  {
680  m_gsTexCoords = texCoords;
681  }
682 
684 
685  void CENSGraphicsShape::addTexCoord(const Vector2f &texCoord)
686  {
687  m_gsTexCoords.push_back(texCoord);
688  }
689 
690 }
int getHeight() const
Computational Embodied Neuroscience Simulator library.
Definition: cens_engine.cpp:29
std::vector< Vector3f > Vertices
Definition: cens_types.h:43
void setColor(const Vector3f &color)
void addNormal(const Vector3f &normal)
int getWidth() const
Vector2f & getTexCoord(int texCoord_index)
void buildAsConvex(const Vertices &vertices, const unsigned int *idx, int nvtxs, int nidxs, int ntrns, const TexCoords &texCoords=CENS_NULL_TEXCOORDS, const Vector3f &color=CENS_NULL_COLOR, CENSPixelMap pixmap=CENS_NULL_PIXMAP)
void buildAsSphere(float radius, const Vector3f &color=CENS_NULL_COLOR, CENSPixelMap pixmap=CENS_NULL_PIXMAP)
std::vector< Vector2f > TexCoords
Definition: cens_types.h:44
Vector3f & getNormal(int normal_index)
void addTexCoord(const Vector2f &texCoord)
void setNormals(const Vertices &normals)
void copyimage(const GLubyte *source)
const int GS_SPHERE_LONGS
Definition: cens_types.cpp:36
void buildAsPlane(const Vector3f &orig, const Vector3f &v1, const Vector3f &v2, const Vector3f &color=CENS_NULL_COLOR, CENSPixelMap pixmap=CENS_NULL_PIXMAP)
Use a byte vector as a matrix.
Definition: cens_pixelmap.h:40
void addVertex(const Vector3f &vertex)
const GLubyte * getData() const
Definition: cens_pixelmap.h:95
Vector3f GS_NULL_COLOR
void buildAsSoft(int numTriangles, const TexCoords &texCoords=CENS_NULL_TEXCOORDS, const Vector3f &color=CENS_NULL_COLOR, CENSPixelMap pixmap=CENS_NULL_PIXMAP)
void setVertices(const Vertices &vertices)
Vector3f & getVertex(int vertex_index)
void setTexCoords(const TexCoords &texCoords)
void buildAsBox(const Vector3f &halfExtents, const Vector3f &color=CENS_NULL_COLOR, CENSPixelMap pixmap=CENS_NULL_PIXMAP)
const int GS_SPHERE_LATS
Definition: cens_types.cpp:35
void draw(const Vector3f &org, const Matrix3f &rot)