Main MRPT website > C++ reference for MRPT 1.9.9
CSetOfTriangles.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
13 #include "opengl_internals.h"
15 #include <mrpt/utils/CStream.h>
16 
17 using namespace mrpt;
18 using namespace mrpt::opengl;
19 using namespace mrpt::poses;
20 using namespace mrpt::utils;
21 using namespace mrpt::math;
22 using namespace std;
23 
25 
26 /*---------------------------------------------------------------
27  render
28  ---------------------------------------------------------------*/
29 void CSetOfTriangles::render_dl() const
30 {
31 #if MRPT_HAS_OPENGL_GLUT
32 
33  if (m_enableTransparency)
34  {
35  // glDisable(GL_DEPTH_TEST);
38  }
39  else
40  {
43  }
44 
46 
47  glEnable(GL_NORMALIZE); // Normalize normals
49 
50  for (it = m_triangles.begin(); it != m_triangles.end(); ++it)
51  {
52  // Compute the normal vector:
53  // ---------------------------------
54  float ax = it->x[1] - it->x[0];
55  float ay = it->y[1] - it->y[0];
56  float az = it->z[1] - it->z[0];
57 
58  float bx = it->x[2] - it->x[0];
59  float by = it->y[2] - it->y[0];
60  float bz = it->z[2] - it->z[0];
61 
62  glNormal3f(ay * bz - az * by, -ax * bz + az * bx, ax * by - ay * bx);
63 
64  glColor4f(it->r[0], it->g[0], it->b[0], it->a[0]);
65  glVertex3f(it->x[0], it->y[0], it->z[0]);
66 
67  glColor4f(it->r[1], it->g[1], it->b[1], it->a[1]);
68  glVertex3f(it->x[1], it->y[1], it->z[1]);
69 
70  glColor4f(it->r[2], it->g[2], it->b[2], it->a[2]);
71  glVertex3f(it->x[2], it->y[2], it->z[2]);
72  }
73 
74  glEnd();
76 
78 #endif
79 }
80 
83 {
87 
92 }
95 {
96  i.ReadBufferFixEndianness(t.x, 3);
97  i.ReadBufferFixEndianness(t.y, 3);
98  i.ReadBufferFixEndianness(t.z, 3);
99 
100  i.ReadBufferFixEndianness(t.r, 3);
101  i.ReadBufferFixEndianness(t.g, 3);
102  i.ReadBufferFixEndianness(t.b, 3);
103  i.ReadBufferFixEndianness(t.a, 3);
104 }
105 
106 /*---------------------------------------------------------------
107  Implements the writing to a CStream capability of
108  CSerializable objects
109  ---------------------------------------------------------------*/
111  mrpt::utils::CStream& out, int* version) const
112 {
113  if (version)
114  *version = 1;
115  else
116  {
117  writeToStreamRender(out);
118  uint32_t n = (uint32_t)m_triangles.size();
119  out << n;
120  for (size_t i = 0; i < n; i++)
121  triangle_writeToStream(out, m_triangles[i]);
122 
123  // Version 1:
124  out << m_enableTransparency;
125  }
126 }
127 
128 /*---------------------------------------------------------------
129  Implements the reading from a CStream capability of
130  CSerializable objects
131  ---------------------------------------------------------------*/
133 {
134  switch (version)
135  {
136  case 0:
137  case 1:
138  {
139  readFromStreamRender(in);
140  uint32_t n;
141  in >> n;
142  m_triangles.assign(n, TTriangle());
143  for (size_t i = 0; i < n; i++)
144  triangle_readFromStream(in, m_triangles[i]);
145 
146  if (version >= 1)
147  in >> m_enableTransparency;
148  else
149  m_enableTransparency = true;
150  }
151  break;
152  default:
154  };
155  polygonsUpToDate = false;
157 }
158 
160  const mrpt::poses::CPose3D& o, double& dist) const
161 {
162  if (!polygonsUpToDate) updatePolygons();
163  return mrpt::math::traceRay(tmpPolygons, o - this->m_pose, dist);
164 }
165 
166 // Helper function. Given two 2D points (y1,z1) and (y2,z2), returns three
167 // coefficients A, B and C so that both points
168 // verify Ay+Bz+C=0
169 // returns true if the coefficients have actually been calculated
170 /*
171 inline bool lineCoefs(const float &y1,const float &z1,const float &y2,const
172 float &z2,float coefs[3]) {
173  if ((y1==y2)&(z1==z2)) return false; //Both points are the same
174  if (y1==y2) {
175  //Equation is y-y1=0
176  coefs[0]=1;
177  coefs[1]=0;
178  coefs[2]=-y1;
179  return true;
180  } else {
181  //Equation is:
182  // z1 - z2 /z2 - z1 \ .
183  // -------y + z + |-------y1 - z1| = 0
184  // y2 - y1 \y2 - y1 /
185  coefs[0]=(z1-z2)/(y2-y1);
186  coefs[1]=1;
187  coefs[2]=((z2-z1)/(y2-y1))*y1-z1;
188  return true;
189  }
190 }
191 */
192 /*
193 bool CSetOfTriangles::traceRayTriangle(const mrpt::poses::CPose3D &transf,double
194 &dist,const float xb[3],const float yb[3],const float zb[3]) {
195  //Computation of the actual coordinates in the beam's system.
196  float x[3];
197  float y[3];
198  float z[3];
199  for (int i=0;i<3;i++) transf.composePoint(xb[i],yb[i],zb[i],x[i],y[i],z[i]);
200 
201  //If the triangle is parallel to the beam, no collision is posible.
202  //The triangle is parallel to the beam if the projection of the triangle to
203 the YZ plane results in a line.
204  float lCoefs[3];
205  if (!lineCoefs(y[0],z[0],y[1],z[1],lCoefs)) return false;
206  else if (lCoefs[0]*y[2]+lCoefs[1]*z[2]+lCoefs[2]==0) return false;
207  //Basic sign check
208  if (x[0]<0&&x[1]<0&&x[2]<0) return false;
209  if (y[0]<0&&y[1]<0&&y[2]<0) return false;
210  if (z[0]<0&&z[1]<0&&z[2]<0) return false;
211  if (y[0]>0&&y[1]>0&&y[2]>0) return false;
212  if (z[0]>0&&z[1]>0&&z[2]>0) return false;
213  //Let M be the following matrix:
214  // /p1\ /x1 y1 z1\ .
215  //M=|p2|=|x2 y2 z2|
216  // \p3/ \x3 y3 z3/
217  //If M has rank 3, then (p1,p2,p3) conform a plane which does not contain
218 the origin (0,0,0).
219  //If M has rank 2, then (p1,p2,p3) may conform either a line or a plane
220 which contains the origin.
221  //If M has a lesser rank, then (p1,p2,p3) do not conform a plane.
222  //Let N be the following matrix:
223  //N=/p2-p1\ = /x1 y1 z1\ .
224  // \p3-p1/ \x3 y3 z3/
225  //Given that the rank of M is 2, if the rank of N is still 2 then (p1,p2,p3)
226 conform a plane; either, a line.
227  float mat[9];
228  for (int i=0;i<3;i++) {
229  mat[3*i]=x[i];
230  mat[3*i+1]=y[i];
231  mat[3*i+2]=z[i];
232  }
233  CMatrixTemplateNumeric<float> M=CMatrixTemplateNumeric<float>(3,3,mat);
234  float d2=0;
235  float mat2[6];
236  switch (M.rank()) {
237  case 3:
238  //M's rank is 3, so the triangle is inside a plane which doesn't
239 pass through (0,0,0).
240  //This plane's equation is Ax+By+Cz+1=0. Since the point we're
241 searching for verifies y=0 and z=0, we
242  //only need to compute A (x=-1/A). We do this using Cramer's method.
243  for (int i=0;i<9;i+=3) mat[i]=1;
244  d2=(CMatrixTemplateNumeric<float>(3,3,mat)).det();
245  if (d2==0) return false;
246  else dist=M.det()/d2;
247  break;
248  case 2:
249  //if N's rank is 2, the triangle is inside a plane containing
250 (0,0,0).
251  //Otherwise, (p1,p2,p3) don't conform a plane.
252  for (int i=0;i<2;i++) {
253  mat2[3*i]=x[i+1]-x[0];
254  mat2[3*i+1]=y[i+1]-y[0];
255  mat2[3*i+2]=z[i+1]-z[0];
256  }
257  if (CMatrixTemplateNumeric<float>(2,3,mat2).rank()==2) dist=0;
258  else return false;
259  break;
260  default:
261  return false;
262  }
263  if (dist<0) return false;
264  //We've already determined the collision point between the beam and the
265 plane, but we need to check if this
266  //point is actually inside the triangle. We do this by projecting the scene
267 into a <x=constant> plane, so
268  //that the triangle is defined by three 2D lines and the beam is the point
269 (y,z)=(0,0).
270 
271  //For each pair of points, we compute the line that they conform, and then
272 we check if the other point's
273  //sign in that line's equation equals that of the origin (that is, both
274 points are on the same side of the line).
275  //If this holds for each one of the three possible combinations, then the
276 point is inside the triangle.
277  //Furthermore, if any of the three equations verify f(0,0)=0, then the point
278 is in the verge of the line, which
279  //is considered as being inside. Note, whichever is the case, that
280 f(0,0)=lCoefs[2].
281 
282  //lineCoefs already contains the coefficients for the first line.
283  if (lCoefs[2]==0) return true;
284  else if (((lCoefs[0]*y[2]+lCoefs[1]*z[2]+lCoefs[2])>0)!=(lCoefs[2]>0))
285 return false;
286  lineCoefs(y[0],z[0],y[2],z[2],lCoefs);
287  if (lCoefs[2]==0) return true;
288  else if (((lCoefs[0]*y[1]+lCoefs[1]*z[1]+lCoefs[2])>0)!=(lCoefs[2]>0))
289 return false;
290  lineCoefs(y[1],z[1],y[2],z[2],lCoefs);
291  if (lCoefs[2]==0) return true;
292  else return ((lCoefs[0]*y[0]+lCoefs[1]*z[0]+lCoefs[2])>0)==(lCoefs[2]>0);
293 }
294 */
295 
297 {
299  m_color = c;
300  mrpt::utils::TColorf col(c);
301  for (std::vector<TTriangle>::iterator it = m_triangles.begin();
302  it != m_triangles.end(); ++it)
303  for (size_t i = 0; i < 3; i++)
304  {
305  it->r[i] = col.R;
306  it->g[i] = col.G;
307  it->b[i] = col.B;
308  it->a[i] = col.A;
309  }
310  return *this;
311 }
312 
314 {
316  m_color.R = r;
317  const float col = r / 255.f;
318  for (std::vector<TTriangle>::iterator it = m_triangles.begin();
319  it != m_triangles.end(); ++it)
320  for (size_t i = 0; i < 3; i++) it->r[i] = col;
321  return *this;
322 }
323 
325 {
327  m_color.G = g;
328  const float col = g / 255.f;
329  for (std::vector<TTriangle>::iterator it = m_triangles.begin();
330  it != m_triangles.end(); ++it)
331  for (size_t i = 0; i < 3; i++) it->g[i] = col;
332  return *this;
333 }
334 
336 {
338  m_color.B = b;
339  const float col = b / 255.f;
340  for (std::vector<TTriangle>::iterator it = m_triangles.begin();
341  it != m_triangles.end(); ++it)
342  for (size_t i = 0; i < 3; i++) it->b[i] = col;
343  return *this;
344 }
345 
347 {
349  m_color.A = a;
350  const float col = a / 255.f;
351  for (std::vector<TTriangle>::iterator it = m_triangles.begin();
352  it != m_triangles.end(); ++it)
353  for (size_t i = 0; i < 3; i++) it->a[i] = col;
354  return *this;
355 }
356 
358  std::vector<mrpt::math::TPolygon3D>& polys) const
359 {
360  if (!polygonsUpToDate) updatePolygons();
361  size_t N = tmpPolygons.size();
362  for (size_t i = 0; i < N; i++) polys[i] = tmpPolygons[i].poly;
363 }
364 
366 {
367  TPolygon3D tmp(3);
368  size_t N = m_triangles.size();
369  tmpPolygons.resize(N);
370  for (size_t i = 0; i < N; i++)
371  for (size_t j = 0; j < 3; j++)
372  {
373  const TTriangle& t = m_triangles[i];
374  tmp[j].x = t.x[j];
375  tmp[j].y = t.y[j];
376  tmp[j].z = t.z[j];
377  tmpPolygons[i] = tmp;
378  }
379  polygonsUpToDate = true;
381 }
382 
384  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
385 {
386  bb_min = mrpt::math::TPoint3D(
387  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
388  std::numeric_limits<double>::max());
389  bb_max = mrpt::math::TPoint3D(
390  -std::numeric_limits<double>::max(),
391  -std::numeric_limits<double>::max(),
392  -std::numeric_limits<double>::max());
393 
394  for (size_t i = 0; i < m_triangles.size(); i++)
395  {
396  const TTriangle& t = m_triangles[i];
397 
398  keep_min(bb_min.x, t.x[0]);
399  keep_max(bb_max.x, t.x[0]);
400  keep_min(bb_min.y, t.y[0]);
401  keep_max(bb_max.y, t.y[0]);
402  keep_min(bb_min.z, t.z[0]);
403  keep_max(bb_max.z, t.z[0]);
404 
405  keep_min(bb_min.x, t.x[1]);
406  keep_max(bb_max.x, t.x[1]);
407  keep_min(bb_min.y, t.y[1]);
408  keep_max(bb_max.y, t.y[1]);
409  keep_min(bb_min.z, t.z[1]);
410  keep_max(bb_max.z, t.z[1]);
411 
412  keep_min(bb_min.x, t.x[2]);
413  keep_max(bb_max.x, t.x[2]);
414  keep_min(bb_min.y, t.y[2]);
415  keep_max(bb_max.y, t.y[2]);
416  keep_min(bb_min.z, t.z[2]);
417  keep_max(bb_max.z, t.z[2]);
418  }
419 
420  // Convert to coordinates of my parent:
421  m_pose.composePoint(bb_min, bb_min);
422  m_pose.composePoint(bb_max, bb_max);
423 }
424 
426 {
427  reserve(m_triangles.size() + p->m_triangles.size());
428  m_triangles.insert(
429  m_triangles.end(), p->m_triangles.begin(), p->m_triangles.end());
430  polygonsUpToDate = false;
432 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLdouble GLdouble t
Definition: glext.h:3689
CRenderizable & setColorG_u8(const uint8_t g) override
Color components in the range [0,255].
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Ray tracing.
GLbyte GLbyte bz
Definition: glext.h:6105
GLAPI void GLAPIENTRY glEnable(GLenum cap)
void getPolygons(std::vector< mrpt::math::TPolygon3D > &polys) const
Gets the polygon cache.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons&#39; properties.
Definition: geometry.cpp:2582
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
GLenum GLsizei n
Definition: glext.h:5074
Scalar * iterator
Definition: eigen_plugins.h:26
#define GL_TRIANGLES
Definition: glew.h:276
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:43
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
STL namespace.
#define GL_NORMALIZE
Definition: glew.h:416
const Scalar * const_iterator
Definition: eigen_plugins.h:27
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
#define GL_DEPTH_TEST
Definition: glew.h:401
std::shared_ptr< CSetOfTriangles > Ptr
static void triangle_readFromStream(mrpt::utils::CStream &i, CSetOfTriangles::TTriangle &t)
CRenderizable & setColorR_u8(const uint8_t r) override
Color components in the range [0,255].
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
unsigned char uint8_t
Definition: rptypes.h:41
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running arch...
Definition: CStream.h:159
static void triangle_writeToStream(mrpt::utils::CStream &o, const CSetOfTriangles::TTriangle &t)
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
const GLubyte * c
Definition: glext.h:6313
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
CRenderizable & setColor_u8(const mrpt::utils::TColor &c) override
Changes the default object color.
GLubyte g
Definition: glext.h:6279
A RGB color - 8bit.
Definition: TColor.h:25
GLubyte GLubyte b
Definition: glext.h:6279
double x
X,Y,Z coordinates.
void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const override
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
GLAPI void GLAPIENTRY glBegin(GLenum mode)
#define GL_BLEND
Definition: glew.h:432
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
Definition: bits.h:227
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
void updatePolygons() const
Polygon cache updating.
#define GL_SRC_ALPHA
Definition: glew.h:286
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
Definition: bits.h:220
size_t ReadBufferFixEndianness(T *ptr, size_t ElementCount)
Reads a sequence of elemental datatypes, taking care of reordering their bytes from the MRPT stream s...
Definition: CStream.h:108
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
GLuint in
Definition: glext.h:7274
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
GLAPI void GLAPIENTRY glEnd(void)
GLbyte by
Definition: glext.h:6105
A set of colored triangles.
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
Lightweight 3D point.
unsigned __int32 uint32_t
Definition: rptypes.h:47
GLAPI void GLAPIENTRY glDisable(GLenum cap)
CRenderizable & setColorB_u8(const uint8_t b) override
Color components in the range [0,255].
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLfloat GLfloat p
Definition: glext.h:6305
CRenderizable & setColorA_u8(const uint8_t a) override
Color components in the range [0,255].
void insertTriangles(const InputIterator &begin, const InputIterator &end)
Inserts a set of triangles, bounded by iterators, into this set.
3D polygon, inheriting from std::vector<TPoint3D>



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019