Main MRPT website > C++ reference for MRPT 1.9.9
COpenGLViewport.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 
16 #include <mrpt/utils/CStringList.h>
17 #include <mrpt/utils/CTimeLogger.h>
18 #include <mrpt/utils/CStream.h>
20 #include <mrpt/opengl/gl_utils.h>
21 
22 #include "opengl_internals.h"
23 
24 using namespace mrpt;
25 using namespace mrpt::poses;
26 using namespace mrpt::opengl;
27 using namespace mrpt::utils;
28 using namespace mrpt::math;
29 using namespace std;
30 
32 using namespace mrpt::utils::metaprogramming;
33 
35 
36 //#define OPENGLVIEWPORT_ENABLE_TIMEPROFILING
37 
38 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
39 mrpt::utils::CTimeLogger glv_timlog;
40 #endif
41 
42 /*--------------------------------------------------------------
43 
44  IMPLEMENTATION OF COpenGLViewport
45 
46  ---------------------------------------------------------------*/
47 
48 /*--------------------------------------------------------------
49  Constructor
50  ---------------------------------------------------------------*/
51 COpenGLViewport::COpenGLViewport(COpenGLScene* parent, const string& name)
52  : m_camera(),
53  m_parent(parent),
54  m_isCloned(false),
55  m_isClonedCamera(false),
56  m_clonedViewport(),
57  m_name(name),
58  m_isTransparent(false),
59  m_borderWidth(0),
60  m_view_x(0),
61  m_view_y(0),
62  m_view_width(1),
63  m_view_height(1),
64  m_clip_min(0.1),
65  m_clip_max(10000),
66  m_custom_backgb_color(false),
67  m_background_color(0.6f, 0.6f, 0.6f),
68  m_isImageView(false),
69  m_imageview_img(),
70  m_objects(),
71  // OpenGL settings:
72  m_OpenGL_enablePolygonNicest(true),
73  m_lights()
74 {
75  // Default: one light from default direction
76  m_lights.push_back(CLight());
77  m_lights.push_back(CLight());
78 
79  m_lights[0].setPosition(1, 1, 1, 0);
80  m_lights[0].setDirection(-1, -1, -1);
81 
82  m_lights[1].light_ID = 1;
83  m_lights[1].setPosition(1, 2, -1, 0);
84  m_lights[1].setDirection(1, 2, 1);
85 
86  m_lights[1].color_diffuse[0] = 0.3f;
87  m_lights[1].color_diffuse[1] = 0.3f;
88  m_lights[1].color_diffuse[2] = 0.3f;
89 
90  m_lights[1].color_ambient[0] = 0.3f;
91  m_lights[1].color_ambient[1] = 0.3f;
92  m_lights[1].color_ambient[2] = 0.3f;
93 }
94 
95 /*--------------------------------------------------------------
96  Destructor
97  ---------------------------------------------------------------*/
99 /*--------------------------------------------------------------
100  setCloneView
101  ---------------------------------------------------------------*/
102 void COpenGLViewport::setCloneView(const string& clonedViewport)
103 {
104  clear();
105  m_isCloned = true;
106  m_clonedViewport = clonedViewport;
107 }
108 
109 /*--------------------------------------------------------------
110  setViewportPosition
111  ---------------------------------------------------------------*/
113  const double x, const double y, const double width, const double height)
114 {
115  MRPT_START
116  ASSERT_(m_view_width > 0)
118 
119  m_view_x = x;
120  m_view_y = y;
123 
124  MRPT_END
125 }
126 
127 /*--------------------------------------------------------------
128  getViewportPosition
129  ---------------------------------------------------------------*/
131  double& x, double& y, double& width, double& height)
132 {
133  x = m_view_x;
134  y = m_view_y;
137 }
138 
139 /*--------------------------------------------------------------
140  clear
141  ---------------------------------------------------------------*/
143 /*--------------------------------------------------------------
144  insert
145  ---------------------------------------------------------------*/
147 {
148  m_objects.push_back(newObject);
149 }
150 
151 /*---------------------------------------------------------------
152  render
153  ---------------------------------------------------------------*/
155  const int render_width, const int render_height) const
156 {
157 #if MRPT_HAS_OPENGL_GLUT
158  const CRenderizable* it =
159  nullptr; // Declared here for usage in the "catch"
160  try
161  {
162  // Change viewport:
163  // -------------------------------------------
164  const GLint vx = m_view_x > 1
165  ? GLint(m_view_x)
166  : (m_view_x < 0 ? GLint(render_width + m_view_x)
167  : GLint(render_width * m_view_x));
168  const GLint vy = m_view_y > 1
169  ? GLint(m_view_y)
170  : (m_view_y < 0 ? GLint(render_height + m_view_y)
171  : GLint(render_height * m_view_y));
172 
173  GLint vw;
174  if (m_view_width > 1) // >1 -> absolute pixels:
175  vw = GLint(m_view_width);
176  else if (m_view_width < 0)
177  { // Negative numbers: Specify the right side coordinates instead of
178  // the width:
179  if (m_view_width >= -1)
180  vw = GLint(-render_width * m_view_width - vx + 1);
181  else
182  vw = GLint(-m_view_width - vx + 1);
183  }
184  else // A factor:
185  {
186  vw = GLint(render_width * m_view_width);
187  }
188 
189  GLint vh;
190  if (m_view_height > 1) // >1 -> absolute pixels:
191  vh = GLint(m_view_height);
192  else if (m_view_height < 0)
193  { // Negative numbers: Specify the right side coordinates instead of
194  // the width:
195  if (m_view_height >= -1)
196  vh = GLint(-render_height * m_view_height - vy + 1);
197  else
198  vh = GLint(-m_view_height - vy + 1);
199  }
200  else // A factor:
201  vh = GLint(render_height * m_view_height);
202 
203  glViewport(vx, vy, vw, vh);
204 
205  // Clear depth&/color buffers:
206  // -------------------------------------------
209 
210  glScissor(vx, vy, vw, vh);
211 
213  if (!m_isTransparent)
214  { // Clear color & depth buffers:
215  // Save?
216  GLdouble old_colors[4];
218  {
219  glGetDoublev(GL_COLOR_CLEAR_VALUE, old_colors);
220  glClearColor(
223  }
224 
225  glClear(
228 
229  // Restore old colors:
231  glClearColor(
232  old_colors[0], old_colors[1], old_colors[2], old_colors[3]);
233  }
234  else
235  { // Clear depth buffer only:
237  }
239 
240  // If we are in "image mode", rendering is much simpler: just set
241  // ortho projection and render the image quad:
242  if (m_isImageView)
243  {
244 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
245  glv_timlog.enter("COpenGLViewport::render imageview");
246 #endif
247  // "Image mode" rendering:
248  // -----------------------------------
249  if (m_imageview_img) // should be ALWAYS true, but just in case!
250  {
251  // Note: The following code is inspired in the implementations:
252  // - libcvd, by Edward Rosten http://www.edwardrosten.com/cvd/
253  // - PTAM, by Klein & Murray
254  // http://www.robots.ox.ac.uk/~gk/PTAM/
255 
256  const mrpt::utils::CImage* img = m_imageview_img.get();
257 
258  const int img_w = img->getWidth();
259  const int img_h = img->getHeight();
260 
261  if (img_w != 0 && img_h != 0)
262  {
263  // Prepare an ortho projection:
265  glLoadIdentity();
266 
267  // Need to adjust the aspect ratio?
268  const double ratio = vw * img_h / double(vh * img_w);
269  double ortho_w = img_w;
270  double ortho_h = img_h;
271  if (ratio > 1)
272  ortho_w *= ratio;
273  else if (ratio != 0)
274  ortho_h /= ratio;
275 
276  glOrtho(-0.5, ortho_h - 0.5, ortho_w - 0.5, -0.5, -1, 1);
277 
278  // Prepare raster pos & pixel copy direction in -Y.
279  glRasterPos2f(-0.5f, -0.5f);
280  glPixelZoom(vw / float(ortho_w), -vh / float(ortho_h));
281 
282  // Prepare image data types:
283  const GLenum img_type = GL_UNSIGNED_BYTE;
284  const int nBytesPerPixel = img->isColor() ? 3 : 1;
285  const bool is_RGB_order =
286  (!::strcmp(
287  img->getChannelsOrder(),
288  "RGB")); // Reverse RGB <-> BGR order?
289  const GLenum img_format =
290  nBytesPerPixel == 3 ? (is_RGB_order ? GL_RGB : GL_BGR)
291  : GL_LUMINANCE;
292 
293  // Send image data to OpenGL:
296  img->getRowStride() / nBytesPerPixel);
297  glDrawPixels(
298  img_w, img_h, img_format, img_type,
299  img->get_unsafe(0, 0));
300  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Reset
302  }
303  }
304 // done.
305 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
306  glv_timlog.leave("COpenGLViewport::render imageview");
307 #endif
308  }
309  else
310  {
311  // Non "image mode" rendering:
312 
313  // Set camera:
314  // -------------------------------------------
316  glLoadIdentity();
317 
318  const CListOpenGLObjects* objectsToRender;
319  COpenGLViewport* viewForGetCamera;
320 
321  if (m_isCloned)
322  { // Clone: render someone's else objects.
323  ASSERT_(m_parent.get() != nullptr);
324 
325  COpenGLViewport::Ptr view =
326  m_parent->getViewport(m_clonedViewport);
327  if (!view)
329  "Cloned viewport '%s' not found in parent COpenGLScene",
330  m_clonedViewport.c_str());
331 
332  objectsToRender = &view->m_objects;
333  viewForGetCamera = m_isClonedCamera
334  ? view.get()
335  : const_cast<COpenGLViewport*>(this);
336  }
337  else
338  { // Normal case: render our own objects:
339  objectsToRender = &m_objects;
340  viewForGetCamera = const_cast<COpenGLViewport*>(this);
341  }
342 
343  // Get camera:
344  // 1st: if there is a CCamera in the scene:
345  CRenderizable::Ptr cam_ptr =
346  viewForGetCamera->getByClass<CCamera>();
347 
348  CCamera* myCamera = nullptr;
349  if (cam_ptr)
350  {
351  myCamera = getAs<CCamera>(cam_ptr);
352  }
353 
354  // 2nd: the internal camera of all viewports:
355  if (!myCamera) myCamera = &viewForGetCamera->m_camera;
356 
358 
359  m_lastProjMat.azimuth = DEG2RAD(myCamera->m_azimuthDeg);
360  m_lastProjMat.elev = DEG2RAD(myCamera->m_elevationDeg);
361 
362  const float dis = max(0.01f, myCamera->m_distanceZoom);
364  myCamera->m_pointingX +
365  dis * cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
367  myCamera->m_pointingY +
368  dis * sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
370  myCamera->m_pointingZ + dis * sin(m_lastProjMat.elev);
371 
372  if (fabs(fabs(myCamera->m_elevationDeg) - 90) > 1e-6)
373  {
374  m_lastProjMat.up.x = 0;
375  m_lastProjMat.up.y = 0;
376  m_lastProjMat.up.z = 1;
377  }
378  else
379  {
380  float sgn = myCamera->m_elevationDeg > 0 ? 1 : -1;
381  m_lastProjMat.up.x =
382  -cos(DEG2RAD(myCamera->m_azimuthDeg)) * sgn;
383  m_lastProjMat.up.y =
384  -sin(DEG2RAD(myCamera->m_azimuthDeg)) * sgn;
385  m_lastProjMat.up.z = 0;
386  }
387 
388  m_lastProjMat.is_projective = myCamera->m_projectiveModel;
389  m_lastProjMat.FOV = myCamera->m_projectiveFOVdeg;
390  m_lastProjMat.pointing.x = myCamera->m_pointingX;
391  m_lastProjMat.pointing.y = myCamera->m_pointingY;
392  m_lastProjMat.pointing.z = myCamera->m_pointingZ;
393  m_lastProjMat.zoom = myCamera->m_distanceZoom;
394 
395  if (myCamera->m_projectiveModel)
396  {
397  gluPerspective(
398  myCamera->m_projectiveFOVdeg, vw / double(vh), m_clip_min,
399  m_clip_max);
401  }
402  else
403  {
404  const double ratio = vw / double(vh);
405  double Ax = myCamera->m_distanceZoom * 0.5;
406  double Ay = myCamera->m_distanceZoom * 0.5;
407 
408  if (ratio > 1)
409  Ax *= ratio;
410  else
411  {
412  if (ratio != 0) Ay /= ratio;
413  }
414 
415  glOrtho(-Ax, Ax, -Ay, Ay, -0.5 * m_clip_max, 0.5 * m_clip_max);
417  }
418 
419  if (myCamera->is6DOFMode())
420  {
421  // In 6DOFMode eye is set viewing towards the direction of the
422  // positive Z axis
423  // Up is set as Y axis
424  mrpt::poses::CPose3D viewDirection, pose, at;
425  viewDirection.z(+1);
426  pose = mrpt::poses::CPose3D(myCamera->getPose());
427  at = pose + viewDirection;
428  gluLookAt(
429  pose.x(), pose.y(), pose.z(), at.x(), at.y(), at.z(),
430  pose.getRotationMatrix()(0, 1),
431  pose.getRotationMatrix()(1, 1),
432  pose.getRotationMatrix()(2, 1));
434  }
435  else
436  {
437  // This command is common to ortho and perspective:
438  gluLookAt(
444  }
445 
446  // Optional pre-Render user code:
447  if (hasSubscribers())
448  {
449  mrptEventGLPreRender ev(this);
450  this->publishEvent(ev);
451  }
452 
453  // Global OpenGL settings:
454  // ---------------------------------
455  glHint(
459 
460  // Render objects:
461  // -------------------------------------------
463  glLoadIdentity();
464 
466  glDepthFunc(GL_LEQUAL); // GL_LESS
467 
468  // Setup lights
469  // -------------------------------------------
475 
476  for (size_t i = 0; i < m_lights.size(); i++)
477  m_lights[i].sendToOpenGL();
478 
479  // Render all the objects:
480  // -------------------------------------------
482 
483  } // end of non "image mode" rendering
484 
485  // Finally, draw the border:
486  // --------------------------------
487  if (m_borderWidth > 0)
488  {
490  glColor4f(0, 0, 0, 1);
492 
494  glLoadIdentity();
496  glLoadIdentity();
497 
498  glDisable(GL_LIGHTING); // Disable lights when drawing lines
500  glVertex2f(-1, -1);
501  glVertex2f(-1, 1);
502  glVertex2f(1, 1);
503  glVertex2f(1, -1);
504  glEnd();
505  glEnable(GL_LIGHTING); // Disable lights when drawing lines
506 
508  }
509 
510  // Optional post-Render user code:
511  if (hasSubscribers())
512  {
513  mrptEventGLPostRender ev(this);
514  this->publishEvent(ev);
515  }
516  }
517  catch (exception& e)
518  {
519  string msg;
520  if (it != nullptr)
521  msg = format(
522  "Exception while rendering a class '%s'\n%s",
523  it->GetRuntimeClass()->className, e.what());
524  else
525  msg = format("Exception while rendering:\n%s", e.what());
526 
527  THROW_EXCEPTION(msg);
528  }
529  catch (...)
530  {
531  THROW_EXCEPTION("Runtime error!");
532  }
533 #else
534  MRPT_UNUSED_PARAM(render_width);
535  MRPT_UNUSED_PARAM(render_height);
537  "The MRPT has been compiled with MRPT_HAS_OPENGL_GLUT=0! OpenGL "
538  "functions are not implemented");
539 #endif
540 }
541 
542 /*---------------------------------------------------------------
543  Implements the writing to a CStream capability of
544  CSerializable objects
545  ---------------------------------------------------------------*/
547  mrpt::utils::CStream& out, int* version) const
548 {
549  if (version)
550  *version = 3;
551  else
552  {
553  // Save data:
557 
558  // Added in v1:
562 
563  // Save objects:
564  uint32_t n;
565  n = (uint32_t)m_objects.size();
566  out << n;
568  it != m_objects.end(); ++it)
569  out << **it;
570 
571  // Added in v2: Global OpenGL settings:
573 
574  // Added in v3: Lights
575  out << m_lights;
576  }
577 }
578 
579 /*---------------------------------------------------------------
580  Implements the reading from a CStream capability of
581  CSerializable objects
582  ---------------------------------------------------------------*/
584 {
585  switch (version)
586  {
587  case 0:
588  case 1:
589  case 2:
590  case 3:
591  {
592  // Load data:
597 
598  // in v1:
599  if (version >= 1)
600  {
604  }
605  else
606  {
607  m_custom_backgb_color = false;
608  }
609 
610  // Load objects:
611  uint32_t n;
612  in >> n;
613  clear();
614  m_objects.resize(n);
615 
616  for_each(
617  m_objects.begin(), m_objects.end(), ObjectReadFromStream(&in));
618 
619  // Added in v2: Global OpenGL settings:
620  if (version >= 2)
621  {
623  }
624  else
625  {
626  // Defaults
627  }
628 
629  // Added in v3: Lights
630  if (version >= 3)
631  in >> m_lights;
632  else
633  {
634  // Default: one light from default direction
635  m_lights.clear();
636  m_lights.push_back(CLight());
637  }
638  }
639  break;
640  default:
642  };
643 }
644 
645 /*---------------------------------------------------------------
646  getByName
647  ---------------------------------------------------------------*/
649 {
650  for (CListOpenGLObjects::iterator it = m_objects.begin();
651  it != m_objects.end(); ++it)
652  {
653  if ((*it)->m_name == str)
654  return *it;
655  else if (
656  (*it)->GetRuntimeClass() ==
658  {
659  CRenderizable::Ptr ret = getAs<CSetOfObjects>(*it)->getByName(str);
660  if (ret) return ret;
661  }
662  }
663  return CRenderizable::Ptr();
664 }
665 
666 /*---------------------------------------------------------------
667  initializeAllTextures
668  ---------------------------------------------------------------*/
670 {
671 #if MRPT_HAS_OPENGL_GLUT
672  for (CListOpenGLObjects::iterator it = m_objects.begin();
673  it != m_objects.end(); ++it)
674  {
675  if (IS_DERIVED(*it, CTexturedObject))
676  getAs<CTexturedObject>(*it)->loadTextureInOpenGL();
677  else if (IS_CLASS(*it, CSetOfObjects))
678  getAs<CSetOfObjects>(*it)->initializeAllTextures();
679  }
680 #endif
681 }
682 
683 /*--------------------------------------------------------------
684  dumpListOfObjects
685  ---------------------------------------------------------------*/
687 {
688  for (CListOpenGLObjects::iterator it = m_objects.begin();
689  it != m_objects.end(); ++it)
690  {
691  // Single obj:
692  string s((*it)->GetRuntimeClass()->className);
693  if ((*it)->m_name.size())
694  s += string(" (") + (*it)->m_name + string(")");
695  lst.add(s);
696 
697  if ((*it)->GetRuntimeClass() ==
699  {
700  utils::CStringList auxLst;
701 
702  getAs<CSetOfObjects>(*it)->dumpListOfObjects(auxLst);
703 
704  for (size_t i = 0; i < auxLst.size(); i++)
705  lst.add(string(" ") + auxLst(i));
706  }
707  }
708 }
709 
710 /*--------------------------------------------------------------
711  removeObject
712  ---------------------------------------------------------------*/
714 {
715  for (CListOpenGLObjects::iterator it = m_objects.begin();
716  it != m_objects.end(); ++it)
717  if (*it == obj)
718  {
719  m_objects.erase(it);
720  return;
721  }
722  else if (
723  (*it)->GetRuntimeClass() ==
725  getAs<CSetOfObjects>(*it)->removeObject(obj);
726 }
727 
728 /*--------------------------------------------------------------
729  setViewportClipDistances
730  ---------------------------------------------------------------*/
732  const double clip_min, const double clip_max)
733 {
734  ASSERT_(clip_max > clip_min);
735 
736  m_clip_min = clip_min;
737  m_clip_max = clip_max;
738 }
739 
740 /*--------------------------------------------------------------
741  getViewportClipDistances
742  ---------------------------------------------------------------*/
744  double& clip_min, double& clip_max) const
745 {
746  clip_min = m_clip_min;
747  clip_max = m_clip_max;
748 }
749 
750 /*--------------------------------------------------------------
751  get3DRayForPixelCoord
752  ---------------------------------------------------------------*/
754  const double x_coord, const double y_coord, mrpt::math::TLine3D& out_ray,
755  mrpt::poses::CPose3D* out_cameraPose) const
756 {
757  ASSERTDEB_(
759 
760  const double ASPECT =
762 
763  // unitary vector between (eye) -> (pointing):
764  TPoint3D pointing_dir;
765  pointing_dir.x = -cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
766  pointing_dir.y = -sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
767  pointing_dir.z = -sin(m_lastProjMat.elev);
768 
769  // The camera X vector (in 3D) can be computed from the camera azimuth
770  // angle:
771  TPoint3D cam_x_3d;
772  cam_x_3d.x = -sin(m_lastProjMat.azimuth);
773  cam_x_3d.y = cos(m_lastProjMat.azimuth);
774  cam_x_3d.z = 0;
775 
776  // The camera real UP vector (in 3D) is the cross product:
777  // X3d x pointing_dir:
778  TPoint3D cam_up_3d;
779  crossProduct3D(cam_x_3d, pointing_dir, cam_up_3d);
780 
782  {
783  // Ortho projection:
784  // -------------------------------
785  double Ax = m_lastProjMat.zoom * 0.5;
786  double Ay = Ax;
787 
788  if (ASPECT > 1)
789  Ax *= ASPECT;
790  else
791  {
792  if (ASPECT != 0) Ay /= ASPECT;
793  }
794 
795  const double point_lx =
796  (-0.5 + x_coord / m_lastProjMat.viewport_width) * 2 * Ax;
797  const double point_ly =
798  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * 2 * Ay;
799 
800  const TPoint3D ray_origin(
801  m_lastProjMat.eye.x + point_lx * cam_x_3d.x +
802  point_ly * cam_up_3d.x,
803  m_lastProjMat.eye.y + point_lx * cam_x_3d.y +
804  point_ly * cam_up_3d.y,
805  m_lastProjMat.eye.z + point_lx * cam_x_3d.z +
806  point_ly * cam_up_3d.z);
807 
808  out_ray.pBase = ray_origin;
809  out_ray.director[0] = pointing_dir.x;
810  out_ray.director[1] = pointing_dir.y;
811  out_ray.director[2] = pointing_dir.z;
812  }
813  else
814  {
815  // Perspective camera
816  // -------------------------------
817 
818  // JL: This can derived from:
819  // http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml
820  // where one arrives to:
821  // tan(FOVx/2) = ASPECT_RATIO * tan(FOVy/2)
822  //
823  const double FOVy = DEG2RAD(m_lastProjMat.FOV);
824  const double FOVx = 2.0 * atan(ASPECT * tan(FOVy * 0.5));
825 
826  const double ang_horz =
827  (-0.5 + x_coord / m_lastProjMat.viewport_width) * FOVx;
828  const double ang_vert =
829  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * FOVy;
830 
831  const TPoint3D l(
832  tan(ang_horz), tan(ang_vert),
833  1.0); // Point in camera local reference frame
834 
835  const TPoint3D ray_director(
836  l.x * cam_x_3d.x + l.y * cam_up_3d.x + l.z * pointing_dir.x,
837  l.x * cam_x_3d.y + l.y * cam_up_3d.y + l.z * pointing_dir.y,
838  l.x * cam_x_3d.z + l.y * cam_up_3d.z + l.z * pointing_dir.z);
839 
840  // Set out ray:
841  out_ray.pBase = m_lastProjMat.eye;
842  out_ray.director[0] = ray_director.x;
843  out_ray.director[1] = ray_director.y;
844  out_ray.director[2] = ray_director.z;
845 
846  } // end projective
847 
848  // Camera pose:
849  if (out_cameraPose)
850  {
852  M.get_unsafe(0, 0) = cam_x_3d.x;
853  M.get_unsafe(1, 0) = cam_x_3d.y;
854  M.get_unsafe(2, 0) = cam_x_3d.z;
855  M.get_unsafe(3, 0) = 0;
856 
857  M.get_unsafe(0, 1) = cam_up_3d.x;
858  M.get_unsafe(1, 1) = cam_up_3d.y;
859  M.get_unsafe(2, 1) = cam_up_3d.z;
860  M.get_unsafe(3, 1) = 0;
861 
862  M.get_unsafe(0, 2) = pointing_dir.x;
863  M.get_unsafe(1, 2) = pointing_dir.y;
864  M.get_unsafe(2, 2) = pointing_dir.z;
865  M.get_unsafe(3, 2) = 0;
866 
867  M.get_unsafe(0, 3) = m_lastProjMat.eye.x;
868  M.get_unsafe(1, 3) = m_lastProjMat.eye.y;
869  M.get_unsafe(2, 3) = m_lastProjMat.eye.z;
870  M.get_unsafe(3, 3) = 1;
871 
872  *out_cameraPose = CPose3D(M);
873  }
874 }
875 
876 MRPT_TODO("Implement a setCurrentCameraFromPose() method")
877 
878 void COpenGLViewport::getCurrentCameraPose(
879  mrpt::poses::CPose3D& out_cameraPose) const
880 {
882  get3DRayForPixelCoord(0, 0, dum, &out_cameraPose);
883 }
884 
885 /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView
886  */
888 {
889  // If this was a m_isImageView, remove the quad object:
891 
892  m_isCloned = false;
893  m_isClonedCamera = false;
894  m_isImageView = false;
895 }
896 
898 {
900 }
902 {
904 }
905 
907  const mrpt::utils::CImage& img, bool is_fast)
908 {
909  // If this is the first time, we have to create the quad object:
911  m_imageview_img = mrpt::make_aligned_shared<mrpt::utils::CImage>();
912  m_isImageView = true;
913 
914  // Update texture image:
915  mrpt::utils::CImage* my_img = m_imageview_img.get();
916 
917  if (!is_fast)
918  *my_img = img;
919  else
920  my_img->copyFastFrom(*const_cast<mrpt::utils::CImage*>(&img));
921 }
922 
923 /** Evaluates the bounding box of this object (including possible children) in
924  * the coordinate frame of the object parent. */
926  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
927 {
928  bb_min = TPoint3D(
929  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
930  std::numeric_limits<double>::max());
931  bb_max = TPoint3D(
932  -std::numeric_limits<double>::max(),
933  -std::numeric_limits<double>::max(),
934  -std::numeric_limits<double>::max());
935 
937  it != m_objects.end(); ++it)
938  {
939  TPoint3D child_bbmin(
940  std::numeric_limits<double>::max(),
941  std::numeric_limits<double>::max(),
942  std::numeric_limits<double>::max());
943  TPoint3D child_bbmax(
944  -std::numeric_limits<double>::max(),
945  -std::numeric_limits<double>::max(),
946  -std::numeric_limits<double>::max());
947  (*it)->getBoundingBox(child_bbmin, child_bbmax);
948 
949  keep_min(bb_min.x, child_bbmin.x);
950  keep_min(bb_min.y, child_bbmin.y);
951  keep_min(bb_min.z, child_bbmin.z);
952 
953  keep_max(bb_max.x, child_bbmax.x);
954  keep_max(bb_max.y, child_bbmax.y);
955  keep_max(bb_max.z, child_bbmax.z);
956  }
957 }
#define CLASS_ID_NAMESPACE(class_name, namespaceName)
Definition: CObject.h:88
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of t...
Definition: CObject.h:103
#define IS_DERIVED(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is an i...
Definition: CObject.h:109
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define DEG2RAD
Definition: bits.h:112
A numeric matrix of compile-time fixed size.
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:31
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives.
Definition: COpenGLScene.h:61
A viewport within a COpenGLScene, containing a set of OpenGL objects to render.
double m_view_x
The viewport position [0,1].
std::string m_clonedViewport
Only if m_isCloned=true.
opengl::CListOpenGLObjects m_objects
The list of objects that comprise the 3D scene.
void setImageView(const mrpt::utils::CImage &img)
Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport a...
void clear()
Delete all internal obejcts.
void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
void setViewportClipDistances(const double clip_min, const double clip_max)
Set the min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
void insert(const CRenderizable::Ptr &newObject)
Insert a new object into the list.
void removeObject(const CRenderizable::Ptr &obj)
Removes the given object from the scene (it also deletes the object to free its memory).
void getViewportPosition(double &x, double &y, double &width, double &height)
Get the current viewport position and dimension on the rendering window.
mrpt::utils::CImage::Ptr m_imageview_img
The image to display, after calling setImageView()
void dumpListOfObjects(mrpt::utils::CStringList &lst)
Retrieves a list of all objects in text form.
bool m_isClonedCamera
Set by setCloneCamera.
uint32_t m_borderWidth
Default=0, the border around the viewport.
void setCloneView(const std::string &clonedViewport)
Set this viewport as a clone of some other viewport, given its name - as a side effect,...
bool m_isTransparent
Whether to clear color buffer.
utils::safe_ptr< COpenGLScene > m_parent
The scene that contains this viewport.
bool m_isImageView
Set by setImageView.
std::shared_ptr< COpenGLViewport > Ptr
void getViewportClipDistances(double &clip_min, double &clip_max) const
Get the current min/max clip depth distances of the rendering frustum (default: 0....
void initializeAllTextures()
Initializes all textures in the scene (See opengl::CTexturedPlane::loadTextureInOpenGL)
void get3DRayForPixelCoord(const double x_coord, const double y_coord, mrpt::math::TLine3D &out_ray, mrpt::poses::CPose3D *out_cameraPose=nullptr) const
Compute the 3D ray corresponding to a given pixel; this can be used to allow the user to pick and sel...
void setImageView_fast(mrpt::utils::CImage &img)
Just like setImageView but moves the internal image memory instead of making a copy,...
opengl::CCamera m_camera
The camera associated to the viewport.
void setNormalMode()
Resets the viewport to a normal 3D viewport.
std::vector< CLight > m_lights
void setViewportPosition(const double x, const double y, const double width, const double height)
Change the viewport position and dimension on the rendering window.
bool m_isCloned
Set by setCloneView.
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...
TLastProjectiveMatrixInfo m_lastProjMat
Info updated with each "render()" and used in "get3DRayForPixelCoord".
double m_clip_min
The min/max clip depth distances (default: 0.1 - 10000)
std::string m_name
The viewport's name.
T::Ptr getByClass(const size_t &ith=0) const
Returns the i'th object of a given class (or of a descendant class), or nullptr (an empty smart point...
mrpt::utils::TColorf m_background_color
used only if m_custom_backgb_color
virtual ~COpenGLViewport()
Destructor: clears all objects.
CRenderizable::Ptr getByName(const std::string &str)
Returns the first object with a given name, or nullptr if not found.
void internal_setImageView_fast(const mrpt::utils::CImage &img, bool is_fast)
void render(const int render_width, const int render_height) const
Render the objects in this viewport (called from COpenGLScene only)
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:44
std::shared_ptr< CRenderizable > Ptr
Definition: CRenderizable.h:45
static void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
A set of object, which are referenced to the coordinates framework established in this object.
Definition: CSetOfObjects.h:31
A base class for all OpenGL objects with loadable textures.
An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives a...
An event sent by an mrpt::opengl::COpenGLViewport just after clearing the viewport and setting the GL...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:89
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:237
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:135
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:119
void copyFastFrom(CImage &o)
Moves an image from another object, erasing the origin image in the process (this is much faster than...
Definition: CImage.cpp:173
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:57
void publishEvent(const mrptEvent &e) const
Called when you want this object to emit an event to all the observers currently subscribed to this o...
Definition: CObservable.cpp:47
The virtual base class which provides a unified interface for all persistent objects in MRPT.
Definition: CSerializable.h:45
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:42
A class for storing a list of text lines.
Definition: CStringList.h:33
void add(const std::string &str)
Appends a new string at the end of the string list.
Definition: CStringList.cpp:43
size_t size() const
Returns the number of text lines in the list.
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X),...
Definition: CTimeLogger.h:46
Scalar * iterator
Definition: eigen_plugins.h:26
const Scalar * const_iterator
Definition: eigen_plugins.h:27
#define GL_TRUE
Definition: glew.h:293
#define GL_FASTEST
Definition: glew.h:568
GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
#define GL_NICEST
Definition: glew.h:569
GLAPI void GLAPIENTRY glDepthFunc(GLenum func)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_ACCUM_BUFFER_BIT
Definition: glew.h:260
GLAPI void GLAPIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
#define GL_AMBIENT_AND_DIFFUSE
Definition: glew.h:608
#define GL_FRONT_AND_BACK
Definition: glew.h:321
#define GL_BGR
Definition: glew.h:1239
GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode)
GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode)
GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y)
#define GL_DEPTH_TEST
Definition: glew.h:401
double GLdouble
Definition: glew.h:219
#define GL_SMOOTH
Definition: glew.h:635
#define GL_LUMINANCE
Definition: glew.h:625
GLAPI void GLAPIENTRY glLoadIdentity(void)
#define GL_RGB
Definition: glew.h:623
unsigned int GLenum
Definition: glew.h:206
#define GL_UNSIGNED_BYTE
Definition: glew.h:302
#define GL_PROJECTION
Definition: glew.h:611
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
#define GL_LEQUAL
Definition: glew.h:246
#define GL_MODELVIEW
Definition: glew.h:610
GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble *params)
GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
#define GL_COLOR_BUFFER_BIT
Definition: glew.h:265
GLAPI void GLAPIENTRY glBegin(GLenum mode)
#define GL_COLOR_MATERIAL
Definition: glew.h:392
GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param)
GLAPI void GLAPIENTRY glEnd(void)
#define GL_SCISSOR_TEST
Definition: glew.h:440
#define GL_STENCIL_BUFFER_BIT
Definition: glew.h:261
#define GL_LINE_LOOP
Definition: glew.h:274
int GLint
Definition: glew.h:209
GLAPI void GLAPIENTRY glDisable(GLenum cap)
#define GL_LIGHT_MODEL_TWO_SIDE
Definition: glew.h:387
GLAPI void GLAPIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
#define GL_PERSPECTIVE_CORRECTION_HINT
Definition: glew.h:450
GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y)
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
#define GL_POLYGON_SMOOTH_HINT
Definition: glew.h:453
#define GL_DEPTH_BUFFER_BIT
Definition: glew.h:259
GLAPI void GLAPIENTRY glMatrixMode(GLenum mode)
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
#define GL_LIGHTING
Definition: glew.h:385
#define GL_UNPACK_ROW_LENGTH
Definition: glew.h:481
GLAPI void GLAPIENTRY glClear(GLbitfield mask)
#define GL_COLOR_CLEAR_VALUE
Definition: glew.h:443
GLenum GLsizei n
Definition: glext.h:5074
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
GLenum GLint GLint y
Definition: glext.h:3538
GLenum GLsizei width
Definition: glext.h:3531
GLuint in
Definition: glext.h:7274
GLint GLvoid * img
Definition: glext.h:3763
GLenum GLint x
Definition: glext.h:3538
GLdouble s
Definition: glext.h:3676
GLuint const GLchar * name
Definition: glext.h:4054
GLenum GLsizei GLsizei height
Definition: glext.h:3554
GLsizei const GLchar ** string
Definition: glext.h:4101
void crossProduct3D(const T &v0, const U &v1, V &vOut)
Computes the cross product of two 3D vectors, returning a vector normal to both.
Definition: geometry.h:822
#define MRPT_TODO(x)
Definition: mrpt_macros.h:82
#define MRPT_START
Definition: mrpt_macros.h:425
#define ASSERT_(f)
Definition: mrpt_macros.h:309
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
Definition: mrpt_macros.h:355
#define MRPT_END
Definition: mrpt_macros.h:429
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: mrpt_macros.h:181
#define THROW_EXCEPTION(msg)
Definition: mrpt_macros.h:111
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
Definition: mrpt_macros.h:365
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: mrpt_macros.h:121
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:20
@ UNINITIALIZED_MATRIX
Definition: math_frwds.h:86
void renderSetOfObjects(const mrpt::opengl::CListOpenGLObjects &objs)
For each object in the list:
Definition: gl_utils.cpp:32
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:16
std::deque< CRenderizable::Ptr > CListOpenGLObjects
A list of objects pointers, automatically managing memory free at destructor, and managing copies cor...
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:18
A set of utility objects for metaprogramming with STL algorithms.
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.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
unsigned __int32 uint32_t
Definition: rptypes.h:47
3D line, represented by a base point and a director vector.
double director[3]
Director vector.
TPoint3D pBase
Base point.
Lightweight 3D point.
double x
X,Y,Z coordinates.
Each of the possible lights of a 3D scene.
Definition: CLight.h:33
float azimuth
Camera elev & azimuth, in radians.
mrpt::math::TPoint3D pointing
The camera points to here.
mrpt::math::TPoint3D eye
The camera is here.
mrpt::math::TPoint3D up
Up vector of the camera.
const char * className
Definition: CObject.h:34
An object for reading objects from a stream, intended for being used in STL algorithms.



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