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 }
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
static void triangle_readFromStream(mrpt::utils::CStream &i, CSetOfTriangles::TTriangle &t)
static void triangle_writeToStream(mrpt::utils::CStream &o, const CSetOfTriangles::TTriangle &t)
3D polygon, inheriting from std::vector<TPoint3D>
A renderizable object suitable for rendering with OpenGL's display lists.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated)
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:44
A set of colored triangles.
CRenderizable & setColorG_u8(const uint8_t g) override
Color components in the range [0,255].
CRenderizable & setColorB_u8(const uint8_t b) override
Color components in the range [0,255].
CRenderizable & setColor_u8(const mrpt::utils::TColor &c) override
Changes the default object color.
void getPolygons(std::vector< mrpt::math::TPolygon3D > &polys) const
Gets the polygon cache.
void updatePolygons() const
Polygon cache updating.
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...
CRenderizable & setColorR_u8(const uint8_t r) override
Color components in the range [0,255].
std::shared_ptr< CSetOfTriangles > Ptr
void insertTriangles(const InputIterator &begin, const InputIterator &end)
Inserts a set of triangles, bounded by iterators, into this set.
CRenderizable & setColorA_u8(const uint8_t a) override
Color components in the range [0,255].
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Ray tracing.
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...
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:89
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:42
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
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
Scalar * iterator
Definition: eigen_plugins.h:26
const Scalar * const_iterator
Definition: eigen_plugins.h:27
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_DEPTH_TEST
Definition: glew.h:401
#define GL_SRC_ALPHA
Definition: glew.h:286
#define GL_NORMALIZE
Definition: glew.h:416
#define GL_TRIANGLES
Definition: glew.h:276
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
GLAPI void GLAPIENTRY glBegin(GLenum mode)
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
#define GL_BLEND
Definition: glew.h:432
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
GLAPI void GLAPIENTRY glEnd(void)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GLdouble GLdouble t
Definition: glext.h:3689
GLenum GLsizei n
Definition: glext.h:5074
GLbyte GLbyte bz
Definition: glext.h:6105
const GLubyte * c
Definition: glext.h:6313
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
GLubyte GLubyte b
Definition: glext.h:6279
GLuint in
Definition: glext.h:7274
GLubyte g
Definition: glext.h:6279
GLfloat GLfloat p
Definition: glext.h:6305
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLbyte by
Definition: glext.h:6105
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
Definition: geometry.cpp:2582
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: mrpt_macros.h:181
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:20
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:16
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:18
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
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
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
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
unsigned __int32 uint32_t
Definition: rptypes.h:47
unsigned char uint8_t
Definition: rptypes.h:41
Lightweight 3D point.
double x
X,Y,Z coordinates.
A RGB color - 8bit.
Definition: TColor.h:26
A RGB color - floats in the range [0,1].
Definition: TColor.h:79



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 63ea9d1f1 Thu Nov 23 00:06:53 2017 +0100 at mar 26 may 2026 12:19:29 CEST