MRPT  1.9.9
COpenGLViewport.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
12 #include <mrpt/math/TLine3D.h>
17 #include <mrpt/opengl/gl_utils.h>
22 
23 #include "opengl_internals.h"
24 
25 using namespace mrpt;
26 using namespace mrpt::poses;
27 using namespace mrpt::opengl;
28 using namespace mrpt::math;
30 using namespace std;
31 
33 
34 //#define OPENGLVIEWPORT_ENABLE_TIMEPROFILING
35 
36 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
37 mrpt::system::CTimeLogger glv_timlog;
38 #endif
39 
40 /*--------------------------------------------------------------
41 
42  IMPLEMENTATION OF COpenGLViewport
43 
44  ---------------------------------------------------------------*/
45 
46 /*--------------------------------------------------------------
47  Constructor
48  ---------------------------------------------------------------*/
49 COpenGLViewport::COpenGLViewport(COpenGLScene* parent, const string& name)
50  : m_camera(),
51  m_parent(parent),
52 
53  m_clonedViewport(),
54  m_name(name),
55 
56  m_background_color(0.6f, 0.6f, 0.6f),
57 
58  m_imageview_img(),
59  m_objects(),
60 
61  m_lights()
62 {
63  // Default: one light from default direction
64  m_lights.emplace_back();
65  m_lights.emplace_back();
66 
67  m_lights[0].setPosition(1, 1, 1, 0);
68  m_lights[0].setDirection(-1, -1, -1);
69 
70  m_lights[1].light_ID = 1;
71  m_lights[1].setPosition(1, 2, -1, 0);
72  m_lights[1].setDirection(1, 2, 1);
73 
74  m_lights[1].color_diffuse[0] = 0.3f;
75  m_lights[1].color_diffuse[1] = 0.3f;
76  m_lights[1].color_diffuse[2] = 0.3f;
77 
78  m_lights[1].color_ambient[0] = 0.3f;
79  m_lights[1].color_ambient[1] = 0.3f;
80  m_lights[1].color_ambient[2] = 0.3f;
81 }
82 
83 /*--------------------------------------------------------------
84  Destructor
85  ---------------------------------------------------------------*/
87 /*--------------------------------------------------------------
88  setCloneView
89  ---------------------------------------------------------------*/
90 void COpenGLViewport::setCloneView(const string& clonedViewport)
91 {
92  clear();
93  m_isCloned = true;
94  m_clonedViewport = clonedViewport;
95 }
96 
97 /*--------------------------------------------------------------
98  setViewportPosition
99  ---------------------------------------------------------------*/
101  const double x, const double y, const double width, const double height)
102 {
103  MRPT_START
104  ASSERT_(m_view_width > 0);
105  ASSERT_(m_view_height > 0);
106 
107  m_view_x = x;
108  m_view_y = y;
111 
112  MRPT_END
113 }
114 
115 /*--------------------------------------------------------------
116  getViewportPosition
117  ---------------------------------------------------------------*/
119  double& x, double& y, double& width, double& height)
120 {
121  x = m_view_x;
122  y = m_view_y;
125 }
126 
127 /*--------------------------------------------------------------
128  clear
129  ---------------------------------------------------------------*/
131 /*--------------------------------------------------------------
132  insert
133  ---------------------------------------------------------------*/
135 {
136  m_objects.push_back(newObject);
137 }
138 
139 /*---------------------------------------------------------------
140  render
141  ---------------------------------------------------------------*/
143  const int render_width, const int render_height) const
144 {
145 #if MRPT_HAS_OPENGL_GLUT
146  const CRenderizable* it =
147  nullptr; // Declared here for usage in the "catch"
148  try
149  {
150  // Change viewport:
151  // -------------------------------------------
152  const GLint vx = m_view_x > 1
153  ? GLint(m_view_x)
154  : (m_view_x < 0 ? GLint(render_width + m_view_x)
155  : GLint(render_width * m_view_x));
156  const GLint vy = m_view_y > 1
157  ? GLint(m_view_y)
158  : (m_view_y < 0 ? GLint(render_height + m_view_y)
159  : GLint(render_height * m_view_y));
160 
161  GLint vw;
162  if (m_view_width > 1) // >1 -> absolute pixels:
163  vw = GLint(m_view_width);
164  else if (m_view_width < 0)
165  { // Negative numbers: Specify the right side coordinates instead of
166  // the width:
167  if (m_view_width >= -1)
168  vw = GLint(-render_width * m_view_width - vx + 1);
169  else
170  vw = GLint(-m_view_width - vx + 1);
171  }
172  else // A factor:
173  {
174  vw = GLint(render_width * m_view_width);
175  }
176 
177  GLint vh;
178  if (m_view_height > 1) // >1 -> absolute pixels:
179  vh = GLint(m_view_height);
180  else if (m_view_height < 0)
181  { // Negative numbers: Specify the right side coordinates instead of
182  // the width:
183  if (m_view_height >= -1)
184  vh = GLint(-render_height * m_view_height - vy + 1);
185  else
186  vh = GLint(-m_view_height - vy + 1);
187  }
188  else // A factor:
189  vh = GLint(render_height * m_view_height);
190 
191  glViewport(vx, vy, vw, vh);
192 
193  // Clear depth&/color buffers:
194  // -------------------------------------------
197 
198  glScissor(vx, vy, vw, vh);
199 
201  if (!m_isTransparent)
202  { // Clear color & depth buffers:
203  // Save?
204  GLdouble old_colors[4];
206  {
207  glGetDoublev(GL_COLOR_CLEAR_VALUE, old_colors);
208  glClearColor(
211  }
212 
213  glClear(
216 
217  // Restore old colors:
219  glClearColor(
220  old_colors[0], old_colors[1], old_colors[2], old_colors[3]);
221  }
222  else
223  { // Clear depth buffer only:
225  }
227 
228  // If we are in "image mode", rendering is much simpler: just set
229  // ortho projection and render the image quad:
230  if (m_isImageView)
231  {
232 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
233  glv_timlog.enter("COpenGLViewport::render imageview");
234 #endif
235  // "Image mode" rendering:
236  // -----------------------------------
237  if (m_imageview_img) // should be ALWAYS true, but just in case!
238  {
239  // Note: The following code is inspired in the implementations:
240  // - libcvd, by Edward Rosten http://www.edwardrosten.com/cvd/
241  // - PTAM, by Klein & Murray
242  // http://www.robots.ox.ac.uk/~gk/PTAM/
243 
245 
246  const int img_w = img->getWidth();
247  const int img_h = img->getHeight();
248 
249  if (img_w != 0 && img_h != 0)
250  {
251  // Prepare an ortho projection:
253  glLoadIdentity();
254 
255  // Need to adjust the aspect ratio?
256  const double ratio = vw * img_h / double(vh * img_w);
257  double ortho_w = img_w;
258  double ortho_h = img_h;
259  if (ratio > 1)
260  ortho_w *= ratio;
261  else if (ratio != 0)
262  ortho_h /= ratio;
263 
264  glOrtho(-0.5, ortho_h - 0.5, ortho_w - 0.5, -0.5, -1, 1);
265 
266  // Prepare raster pos & pixel copy direction in -Y.
267  glRasterPos2f(-0.5f, -0.5f);
268  glPixelZoom(vw / float(ortho_w), -vh / float(ortho_h));
269 
270  // Prepare image data types:
271  const GLenum img_type = GL_UNSIGNED_BYTE;
272  const int nBytesPerPixel = img->isColor() ? 3 : 1;
273  // Reverse RGB <-> BGR order?
274  const bool is_RGB_order =
275  (img->getChannelsOrder() == std::string("RGB"));
276  const GLenum img_format =
277  nBytesPerPixel == 3 ? (is_RGB_order ? GL_RGB : GL_BGR)
278  : GL_LUMINANCE;
279 
280  // autodetect image row alignment, if any:
281  const auto row_stride = img->getRowStride();
282  const auto row_bytes = img->getWidth() * nBytesPerPixel;
283 
284  ASSERT_ABOVEEQ_(row_stride, row_bytes);
285 
286  // Alignment in bytes. Refer to OpenGL docs for
287  // GL_UNPACK_ALIGNMENT
288  const int img_store_alignment =
289  (row_stride - row_bytes) + 1;
290  ASSERT_(
291  img_store_alignment == 1 || img_store_alignment == 2 ||
292  img_store_alignment == 4 || img_store_alignment == 8);
293 
294  // Send image data to OpenGL:
295  glPixelStorei(GL_UNPACK_ALIGNMENT, img_store_alignment);
296  glPixelStorei(GL_UNPACK_ROW_LENGTH, img->getWidth());
297  glDrawPixels(
298  img_w, img_h, img_format, img_type,
299  img->ptrLine<uint8_t>(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 = dynamic_cast<CCamera*>(cam_ptr.get());
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 (const auto& m_light : m_lights) m_light.sendToOpenGL();
477 
478  // Render all the objects:
479  // -------------------------------------------
481 
482  } // end of non "image mode" rendering
483 
484  // Finally, draw the border:
485  // --------------------------------
486  if (m_borderWidth > 0)
487  {
489  glColor4f(0, 0, 0, 1);
491 
493  glLoadIdentity();
495  glLoadIdentity();
496 
497  glDisable(GL_LIGHTING); // Disable lights when drawing lines
499  glVertex2f(-1, -1);
500  glVertex2f(-1, 1);
501  glVertex2f(1, 1);
502  glVertex2f(1, -1);
503  glEnd();
504  glEnable(GL_LIGHTING); // Disable lights when drawing lines
505 
507  }
508 
509  // Optional post-Render user code:
510  if (hasSubscribers())
511  {
512  mrptEventGLPostRender ev(this);
513  this->publishEvent(ev);
514  }
515  }
516  catch (exception& e)
517  {
518  string msg;
519  if (it != nullptr)
520  msg = format(
521  "Exception while rendering a class '%s'\n%s",
522  it->GetRuntimeClass()->className, e.what());
523  else
524  msg = format("Exception while rendering:\n%s", e.what());
525 
526  THROW_EXCEPTION(msg);
527  }
528  catch (...)
529  {
530  THROW_EXCEPTION("Runtime error!");
531  }
532 #else
533  MRPT_UNUSED_PARAM(render_width);
534  MRPT_UNUSED_PARAM(render_height);
536  "The MRPT has been compiled with MRPT_HAS_OPENGL_GLUT=0! OpenGL "
537  "functions are not implemented");
538 #endif
539 }
540 
541 uint8_t COpenGLViewport::serializeGetVersion() const { return 3; }
543 {
544  // Save data:
548 
549  // Added in v1:
552 
553  // Save objects:
554  uint32_t n;
555  n = (uint32_t)m_objects.size();
556  out << n;
557  for (const auto& m_object : m_objects) out << *m_object;
558 
559  // Added in v2: Global OpenGL settings:
561 
562  // Added in v3: Lights
563  out << m_lights;
564 }
565 
567  mrpt::serialization::CArchive& in, uint8_t version)
568 {
569  switch (version)
570  {
571  case 0:
572  case 1:
573  case 2:
574  case 3:
575  {
576  // Load data:
581 
582  // in v1:
583  if (version >= 1)
584  {
588  }
589  else
590  {
591  m_custom_backgb_color = false;
592  }
593 
594  // Load objects:
595  uint32_t n;
596  in >> n;
597  clear();
598  m_objects.resize(n);
599 
600  for_each(
601  m_objects.begin(), m_objects.end(), ObjectReadFromStream(&in));
602 
603  // Added in v2: Global OpenGL settings:
604  if (version >= 2)
605  {
607  }
608  else
609  {
610  // Defaults
611  }
612 
613  // Added in v3: Lights
614  if (version >= 3)
615  in >> m_lights;
616  else
617  {
618  // Default: one light from default direction
619  m_lights.clear();
620  m_lights.emplace_back();
621  }
622  }
623  break;
624  default:
626  };
627 }
628 
629 /*---------------------------------------------------------------
630  getByName
631  ---------------------------------------------------------------*/
633 {
634  for (auto& m_object : m_objects)
635  {
636  if (m_object->m_name == str)
637  return m_object;
638  else if (
639  m_object->GetRuntimeClass() ==
641  {
642  CRenderizable::Ptr ret =
643  std::dynamic_pointer_cast<CSetOfObjects>(m_object)->getByName(
644  str);
645  if (ret) return ret;
646  }
647  }
648  return CRenderizable::Ptr();
649 }
650 
651 /*---------------------------------------------------------------
652  initializeAllTextures
653  ---------------------------------------------------------------*/
655 {
656 #if MRPT_HAS_OPENGL_GLUT
657  for (auto& obj : m_objects)
658  {
660  std::dynamic_pointer_cast<CTexturedObject>(obj)
661  ->loadTextureInOpenGL();
662  else if (IS_CLASS(*obj, CSetOfObjects))
663  std::dynamic_pointer_cast<CSetOfObjects>(obj)
665  }
666 #endif
667 }
668 
669 void COpenGLViewport::dumpListOfObjects(std::vector<std::string>& lst)
670 {
671  for (auto& m_object : m_objects)
672  {
673  // Single obj:
674  string s(m_object->GetRuntimeClass()->className);
675  if (m_object->m_name.size())
676  s += string(" (") + m_object->m_name + string(")");
677  lst.emplace_back(s);
678 
679  if (m_object->GetRuntimeClass() ==
681  {
682  std::vector<std::string> auxLst;
683 
684  dynamic_cast<CSetOfObjects*>(m_object.get())
685  ->dumpListOfObjects(auxLst);
686 
687  for (const auto& i : auxLst) lst.emplace_back(string(" ") + i);
688  }
689  }
690 }
691 
692 /*--------------------------------------------------------------
693  removeObject
694  ---------------------------------------------------------------*/
696 {
697  for (auto it = m_objects.begin(); it != m_objects.end(); ++it)
698  if (*it == obj)
699  {
700  m_objects.erase(it);
701  return;
702  }
703  else if (
704  (*it)->GetRuntimeClass() ==
706  dynamic_cast<CSetOfObjects*>(it->get())->removeObject(obj);
707 }
708 
709 /*--------------------------------------------------------------
710  setViewportClipDistances
711  ---------------------------------------------------------------*/
713  const double clip_min, const double clip_max)
714 {
715  ASSERT_(clip_max > clip_min);
716 
717  m_clip_min = clip_min;
718  m_clip_max = clip_max;
719 }
720 
721 /*--------------------------------------------------------------
722  getViewportClipDistances
723  ---------------------------------------------------------------*/
725  double& clip_min, double& clip_max) const
726 {
727  clip_min = m_clip_min;
728  clip_max = m_clip_max;
729 }
730 
731 /*--------------------------------------------------------------
732  get3DRayForPixelCoord
733  ---------------------------------------------------------------*/
735  const double x_coord, const double y_coord, mrpt::math::TLine3D& out_ray,
736  mrpt::poses::CPose3D* out_cameraPose) const
737 {
738  ASSERTDEB_(
740 
741  const double ASPECT =
743 
744  // unitary vector between (eye) -> (pointing):
745  TPoint3D pointing_dir;
746  pointing_dir.x = -cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
747  pointing_dir.y = -sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
748  pointing_dir.z = -sin(m_lastProjMat.elev);
749 
750  // The camera X vector (in 3D) can be computed from the camera azimuth
751  // angle:
752  TPoint3D cam_x_3d;
753  cam_x_3d.x = -sin(m_lastProjMat.azimuth);
754  cam_x_3d.y = cos(m_lastProjMat.azimuth);
755  cam_x_3d.z = 0;
756 
757  // The camera real UP vector (in 3D) is the cross product:
758  // X3d x pointing_dir:
759  TPoint3D cam_up_3d;
760  crossProduct3D(cam_x_3d, pointing_dir, cam_up_3d);
761 
763  {
764  // Ortho projection:
765  // -------------------------------
766  double Ax = m_lastProjMat.zoom * 0.5;
767  double Ay = Ax;
768 
769  if (ASPECT > 1)
770  Ax *= ASPECT;
771  else
772  {
773  if (ASPECT != 0) Ay /= ASPECT;
774  }
775 
776  const double point_lx =
777  (-0.5 + x_coord / m_lastProjMat.viewport_width) * 2 * Ax;
778  const double point_ly =
779  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * 2 * Ay;
780 
781  const TPoint3D ray_origin(
782  m_lastProjMat.eye.x + point_lx * cam_x_3d.x +
783  point_ly * cam_up_3d.x,
784  m_lastProjMat.eye.y + point_lx * cam_x_3d.y +
785  point_ly * cam_up_3d.y,
786  m_lastProjMat.eye.z + point_lx * cam_x_3d.z +
787  point_ly * cam_up_3d.z);
788 
789  out_ray.pBase = ray_origin;
790  out_ray.director[0] = pointing_dir.x;
791  out_ray.director[1] = pointing_dir.y;
792  out_ray.director[2] = pointing_dir.z;
793  }
794  else
795  {
796  // Perspective camera
797  // -------------------------------
798 
799  // JL: This can be derived from:
800  // http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml
801  // where one arrives to:
802  // tan(FOVx/2) = ASPECT_RATIO * tan(FOVy/2)
803  //
804  const double FOVy = DEG2RAD(m_lastProjMat.FOV);
805  const double FOVx = 2.0 * atan(ASPECT * tan(FOVy * 0.5));
806 
807  const auto vw = m_lastProjMat.viewport_width;
808  const auto vh = m_lastProjMat.viewport_height;
809  const double len_horz = 2.0 * (-0.5 + x_coord / vw) * tan(0.5 * FOVx);
810  const double len_vert = -2.0 * (-0.5 + y_coord / vh) * tan(0.5 * FOVy);
811  // Point in camera local reference frame
812  const auto l = mrpt::math::TPoint3D(len_horz, len_vert, 1.0);
813 
814  const mrpt::math::TPoint3D ray_director(
815  l.x * cam_x_3d.x + l.y * cam_up_3d.x + l.z * pointing_dir.x,
816  l.x * cam_x_3d.y + l.y * cam_up_3d.y + l.z * pointing_dir.y,
817  l.x * cam_x_3d.z + l.y * cam_up_3d.z + l.z * pointing_dir.z);
818 
819  // Set out ray:
820  out_ray.pBase = m_lastProjMat.eye;
821  out_ray.director[0] = ray_director.x;
822  out_ray.director[1] = ray_director.y;
823  out_ray.director[2] = ray_director.z;
824 
825  } // end projective
826 
827  // Camera pose:
828  if (out_cameraPose)
829  {
831  M(0, 0) = cam_x_3d.x;
832  M(1, 0) = cam_x_3d.y;
833  M(2, 0) = cam_x_3d.z;
834  M(3, 0) = 0;
835 
836  M(0, 1) = cam_up_3d.x;
837  M(1, 1) = cam_up_3d.y;
838  M(2, 1) = cam_up_3d.z;
839  M(3, 1) = 0;
840 
841  M(0, 2) = pointing_dir.x;
842  M(1, 2) = pointing_dir.y;
843  M(2, 2) = pointing_dir.z;
844  M(3, 2) = 0;
845 
846  M(0, 3) = m_lastProjMat.eye.x;
847  M(1, 3) = m_lastProjMat.eye.y;
848  M(2, 3) = m_lastProjMat.eye.z;
849  M(3, 3) = 1;
850 
851  *out_cameraPose = CPose3D(M);
852  }
853 }
854 
855 MRPT_TODO("Implement a setCurrentCameraFromPose() method")
856 
857 void COpenGLViewport::getCurrentCameraPose(
858  mrpt::poses::CPose3D& out_cameraPose) const
859 {
861  get3DRayForPixelCoord(0, 0, dum, &out_cameraPose);
862 }
863 
864 /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView
865  */
867 {
868  // If this was a m_isImageView, remove the quad object:
870 
871  m_isCloned = false;
872  m_isClonedCamera = false;
873  m_isImageView = false;
874 }
875 
877 {
879  *m_imageview_img = img;
880 }
882 {
884  *m_imageview_img = std::move(img);
885 }
886 
888 {
889  // If this is the first time, we have to create the quad object:
892  m_isImageView = true;
893 }
894 
895 /** Evaluates the bounding box of this object (including possible children) in
896  * the coordinate frame of the object parent. */
899 {
900  bb_min = TPoint3D(
901  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
902  std::numeric_limits<double>::max());
903  bb_max = TPoint3D(
904  -std::numeric_limits<double>::max(),
905  -std::numeric_limits<double>::max(),
906  -std::numeric_limits<double>::max());
907 
908  for (const auto& m_object : m_objects)
909  {
910  TPoint3D child_bbmin(
911  std::numeric_limits<double>::max(),
912  std::numeric_limits<double>::max(),
913  std::numeric_limits<double>::max());
914  TPoint3D child_bbmax(
915  -std::numeric_limits<double>::max(),
916  -std::numeric_limits<double>::max(),
917  -std::numeric_limits<double>::max());
918  m_object->getBoundingBox(child_bbmin, child_bbmax);
919 
920  keep_min(bb_min.x, child_bbmin.x);
921  keep_min(bb_min.y, child_bbmin.y);
922  keep_min(bb_min.z, child_bbmin.z);
923 
924  keep_max(bb_max.x, child_bbmax.x);
925  keep_max(bb_max.y, child_bbmax.y);
926  keep_max(bb_max.z, child_bbmax.z);
927  }
928 }
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
#define GL_BGR
Definition: glew.h:1262
An object for reading objects from a stream, intended for being used in STL algorithms.
opengl::CListOpenGLObjects m_objects
The list of objects that comprise the 3D scene.
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
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...
A compile-time fixed-size numeric matrix container.
Definition: CMatrixFixed.h:33
CRenderizable::Ptr getByName(const std::string &str)
Returns the first object with a given name, or nullptr if not found.
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...
#define MRPT_START
Definition: exceptions.h:241
double x
X,Y,Z coordinates.
Definition: TPoint3D.h:83
GLAPI void GLAPIENTRY glMatrixMode(GLenum mode)
double GLdouble
Definition: glew.h:220
GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
A base class for all OpenGL objects with loadable textures.
bool m_isTransparent
Whether to clear color buffer.
A set of object, which are referenced to the coordinates framework established in this object...
Definition: CSetOfObjects.h:26
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
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, current list of internal OpenGL objects is cleared.
static Ptr Create(Args &&... args)
Definition: img/CImage.h:149
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
#define GL_STENCIL_BUFFER_BIT
Definition: glew.h:262
float azimuth
Camera elev & azimuth, in radians.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
#define GL_MODELVIEW
Definition: glew.h:611
#define GL_FRONT_AND_BACK
Definition: glew.h:322
std::deque< CRenderizable::Ptr > CListOpenGLObjects
A list of objects pointers, automatically managing memory free at destructor, and managing copies cor...
std::vector< CLight > m_lights
GLenum GLsizei n
Definition: glext.h:5136
void getViewportClipDistances(double &clip_min, double &clip_max) const
Get the current min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:40
void setImageView(const mrpt::img::CImage &img)
Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport a...
std::shared_ptr< CRenderizable > Ptr
Definition: CRenderizable.h:42
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) ...
TPoint3D pBase
Base point.
Definition: TLine3D.h:23
STL namespace.
#define GL_UNSIGNED_BYTE
Definition: glew.h:303
mrpt::img::CImage::Ptr m_imageview_img
The image to display, after calling setImageView()
#define GL_PERSPECTIVE_CORRECTION_HINT
Definition: glew.h:451
#define GL_COLOR_MATERIAL
Definition: glew.h:393
#define GL_DEPTH_TEST
Definition: glew.h:402
#define GL_SMOOTH
Definition: glew.h:636
mrpt::math::TPoint3D eye
The camera is here.
GLdouble s
Definition: glext.h:3682
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
#define GL_LIGHTING
Definition: glew.h:386
GLsizei GLsizei GLuint * obj
Definition: glext.h:4085
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
A viewport within a COpenGLScene, containing a set of OpenGL objects to render.
GLAPI void GLAPIENTRY glLoadIdentity(void)
mrpt::safe_ptr< COpenGLScene > m_parent
The scene that contains this viewport.
GLenum GLsizei width
Definition: glext.h:3535
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:804
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:97
bool m_isClonedCamera
Set by setCloneCamera.
double m_clip_min
The min/max clip depth distances (default: 0.1 - 10000)
GLAPI void GLAPIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble *params)
#define GL_DEPTH_BUFFER_BIT
Definition: glew.h:260
#define GL_COLOR_BUFFER_BIT
Definition: glew.h:266
This base provides a set of functions for maths stuff.
bool m_isImageView
Set by setImageView.
#define GL_COLOR_CLEAR_VALUE
Definition: glew.h:444
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...
GLAPI void GLAPIENTRY glDepthFunc(GLenum func)
std::array< double, 3 > director
Director vector.
Definition: TLine3D.h:25
const char * className
Definition: CObject.h:34
#define GL_LEQUAL
Definition: glew.h:247
constexpr double DEG2RAD(const double x)
Degrees to radians.
void render(const int render_width, const int render_height) const
Render the objects in this viewport (called from COpenGLScene only)
GLint GLvoid * img
Definition: glext.h:3769
~COpenGLViewport() override
Destructor: clears all objects.
#define IS_DERIVED(obj, class_name)
True if the given reference to object (derived from mrpt::rtti::CObject) is an instance of the given ...
Definition: CObject.h:151
GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode)
GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
void removeObject(const CRenderizable::Ptr &obj)
Removes the given object from the scene (it also deletes the object to free its memory).
#define GL_PROJECTION
Definition: glew.h:612
#define IS_CLASS(obj, class_name)
True if the given reference to object (derived from mrpt::rtti::CObject) is of the given class...
Definition: CObject.h:146
#define GL_RGB
Definition: glew.h:624
mrpt::math::TPoint3D up
Up vector of the camera.
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:143
TLastProjectiveMatrixInfo m_lastProjMat
Info updated with each "render()" and used in "get3DRayForPixelCoord".
void setNormalMode()
Resets the viewport to a normal 3D viewport.
GLAPI void GLAPIENTRY glBegin(GLenum mode)
#define ASSERT_ABOVEEQ_(__A, __B)
Definition: exceptions.h:167
GLsizei const GLchar ** string
Definition: glext.h:4116
#define GL_LINE_LOOP
Definition: glew.h:275
GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode)
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
virtual const mrpt::rtti::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
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...
mrpt::math::TPoint3D pointing
The camera points to here.
void initializeAllTextures()
Initializes all textures in the scene (See opengl::CTexturedPlane::loadTextureInOpenGL) ...
#define CLASS_ID_NAMESPACE(class_name, namespaceName)
Definition: CObject.h:105
unsigned int GLenum
Definition: glew.h:207
GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param)
static void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
#define GL_UNPACK_ROW_LENGTH
Definition: glew.h:482
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:54
void clear()
Delete all internal obejcts.
#define MRPT_TODO(x)
Definition: common.h:129
#define GL_UNPACK_ALIGNMENT
Definition: glew.h:485
#define GL_NICEST
Definition: glew.h:570
An event sent by an mrpt::opengl::COpenGLViewport just after clearing the viewport and setting the GL...
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:85
mrpt::vision::TStereoCalibResults out
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
Definition: exceptions.h:190
An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives a...
#define GL_SCISSOR_TEST
Definition: glew.h:441
GLAPI void GLAPIENTRY glClear(GLbitfield mask)
#define MRPT_END
Definition: exceptions.h:245
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:57
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:53
GLuint in
Definition: glext.h:7391
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
GLuint const GLchar * name
Definition: glext.h:4068
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:58
const auto bb_max
GLAPI void GLAPIENTRY glEnd(void)
std::string m_clonedViewport
Only if m_isCloned=true.
#define GL_POLYGON_SMOOTH_HINT
Definition: glew.h:454
mrpt::img::TColorf m_background_color
used only if m_custom_backgb_color
GLenum GLint GLint y
Definition: glext.h:3542
#define GL_LIGHT_MODEL_TWO_SIDE
Definition: glew.h:388
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
T::Ptr getByClass(const size_t &ith=0) const
Returns the i&#39;th object of a given class (or of a descendant class), or nullptr (an empty smart point...
const auto bb_min
int GLint
Definition: glew.h:210
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GLAPI void GLAPIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
GLenum GLint x
Definition: glext.h:3542
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:225
Lightweight 3D point.
Definition: TPoint3D.h:90
void renderSetOfObjects(const mrpt::opengl::CListOpenGLObjects &objs)
For each object in the list:
Definition: gl_utils.cpp:35
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:27
GLenum GLsizei GLsizei height
Definition: glext.h:3558
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: exceptions.h:69
GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
void setViewportPosition(const double x, const double y, const double width, const double height)
Change the viewport position and dimension on the rendering window.
void dumpListOfObjects(std::vector< std::string > &lst)
Retrieves a list of all objects in text form.
#define GL_AMBIENT_AND_DIFFUSE
Definition: glew.h:609
#define GL_ACCUM_BUFFER_BIT
Definition: glew.h:261
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
void getViewportPosition(double &x, double &y, double &width, double &height)
Get the current viewport position and dimension on the rendering window.
void insert(const CRenderizable::Ptr &newObject)
Insert a new object into the list.
double m_view_x
The viewport position [0,1].
GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y)
#define GL_LUMINANCE
Definition: glew.h:626
#define GL_TRUE
Definition: glew.h:294
opengl::CCamera m_camera
The camera associated to the viewport.
std::string m_name
The viewport&#39;s name.
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:147
bool m_isCloned
Set by setCloneView.
3D line, represented by a base point and a director vector.
Definition: TLine3D.h:19
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
#define GL_FASTEST
Definition: glew.h:569



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 70be1f8ba Thu Nov 14 20:53:42 2019 +0100 at jue nov 14 21:00:10 CET 2019