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  // Send image data to OpenGL:
282  glPixelStorei(GL_UNPACK_ROW_LENGTH, img->getWidth());
283  glDrawPixels(
284  img_w, img_h, img_format, img_type,
285  img->ptrLine<uint8_t>(0));
286  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Reset
288  }
289  }
290 // done.
291 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
292  glv_timlog.leave("COpenGLViewport::render imageview");
293 #endif
294  }
295  else
296  {
297  // Non "image mode" rendering:
298 
299  // Set camera:
300  // -------------------------------------------
302  glLoadIdentity();
303 
304  const CListOpenGLObjects* objectsToRender;
305  COpenGLViewport* viewForGetCamera;
306 
307  if (m_isCloned)
308  { // Clone: render someone's else objects.
309  ASSERT_(m_parent.get() != nullptr);
310 
311  COpenGLViewport::Ptr view =
312  m_parent->getViewport(m_clonedViewport);
313  if (!view)
315  "Cloned viewport '%s' not found in parent COpenGLScene",
316  m_clonedViewport.c_str());
317 
318  objectsToRender = &view->m_objects;
319  viewForGetCamera = m_isClonedCamera
320  ? view.get()
321  : const_cast<COpenGLViewport*>(this);
322  }
323  else
324  { // Normal case: render our own objects:
325  objectsToRender = &m_objects;
326  viewForGetCamera = const_cast<COpenGLViewport*>(this);
327  }
328 
329  // Get camera:
330  // 1st: if there is a CCamera in the scene:
331  CRenderizable::Ptr cam_ptr =
332  viewForGetCamera->getByClass<CCamera>();
333 
334  CCamera* myCamera = nullptr;
335  if (cam_ptr)
336  {
337  myCamera = dynamic_cast<CCamera*>(cam_ptr.get());
338  }
339 
340  // 2nd: the internal camera of all viewports:
341  if (!myCamera) myCamera = &viewForGetCamera->m_camera;
342 
344 
345  m_lastProjMat.azimuth = DEG2RAD(myCamera->m_azimuthDeg);
346  m_lastProjMat.elev = DEG2RAD(myCamera->m_elevationDeg);
347 
348  const float dis = max(0.01f, myCamera->m_distanceZoom);
350  myCamera->m_pointingX +
351  dis * cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
353  myCamera->m_pointingY +
354  dis * sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
356  myCamera->m_pointingZ + dis * sin(m_lastProjMat.elev);
357 
358  if (fabs(fabs(myCamera->m_elevationDeg) - 90) > 1e-6)
359  {
360  m_lastProjMat.up.x = 0;
361  m_lastProjMat.up.y = 0;
362  m_lastProjMat.up.z = 1;
363  }
364  else
365  {
366  float sgn = myCamera->m_elevationDeg > 0 ? 1 : -1;
367  m_lastProjMat.up.x =
368  -cos(DEG2RAD(myCamera->m_azimuthDeg)) * sgn;
369  m_lastProjMat.up.y =
370  -sin(DEG2RAD(myCamera->m_azimuthDeg)) * sgn;
371  m_lastProjMat.up.z = 0;
372  }
373 
374  m_lastProjMat.is_projective = myCamera->m_projectiveModel;
375  m_lastProjMat.FOV = myCamera->m_projectiveFOVdeg;
376  m_lastProjMat.pointing.x = myCamera->m_pointingX;
377  m_lastProjMat.pointing.y = myCamera->m_pointingY;
378  m_lastProjMat.pointing.z = myCamera->m_pointingZ;
379  m_lastProjMat.zoom = myCamera->m_distanceZoom;
380 
381  if (myCamera->m_projectiveModel)
382  {
383  gluPerspective(
384  myCamera->m_projectiveFOVdeg, vw / double(vh), m_clip_min,
385  m_clip_max);
387  }
388  else
389  {
390  const double ratio = vw / double(vh);
391  double Ax = myCamera->m_distanceZoom * 0.5;
392  double Ay = myCamera->m_distanceZoom * 0.5;
393 
394  if (ratio > 1)
395  Ax *= ratio;
396  else
397  {
398  if (ratio != 0) Ay /= ratio;
399  }
400 
401  glOrtho(-Ax, Ax, -Ay, Ay, -0.5 * m_clip_max, 0.5 * m_clip_max);
403  }
404 
405  if (myCamera->is6DOFMode())
406  {
407  // In 6DOFMode eye is set viewing towards the direction of the
408  // positive Z axis
409  // Up is set as Y axis
410  mrpt::poses::CPose3D viewDirection, pose, at;
411  viewDirection.z(+1);
412  pose = mrpt::poses::CPose3D(myCamera->getPose());
413  at = pose + viewDirection;
414  gluLookAt(
415  pose.x(), pose.y(), pose.z(), at.x(), at.y(), at.z(),
416  pose.getRotationMatrix()(0, 1),
417  pose.getRotationMatrix()(1, 1),
418  pose.getRotationMatrix()(2, 1));
420  }
421  else
422  {
423  // This command is common to ortho and perspective:
424  gluLookAt(
430  }
431 
432  // Optional pre-Render user code:
433  if (hasSubscribers())
434  {
435  mrptEventGLPreRender ev(this);
436  this->publishEvent(ev);
437  }
438 
439  // Global OpenGL settings:
440  // ---------------------------------
441  glHint(
445 
446  // Render objects:
447  // -------------------------------------------
449  glLoadIdentity();
450 
452  glDepthFunc(GL_LEQUAL); // GL_LESS
453 
454  // Setup lights
455  // -------------------------------------------
461 
462  for (const auto& m_light : m_lights) m_light.sendToOpenGL();
463 
464  // Render all the objects:
465  // -------------------------------------------
467 
468  } // end of non "image mode" rendering
469 
470  // Finally, draw the border:
471  // --------------------------------
472  if (m_borderWidth > 0)
473  {
475  glColor4f(0, 0, 0, 1);
477 
479  glLoadIdentity();
481  glLoadIdentity();
482 
483  glDisable(GL_LIGHTING); // Disable lights when drawing lines
485  glVertex2f(-1, -1);
486  glVertex2f(-1, 1);
487  glVertex2f(1, 1);
488  glVertex2f(1, -1);
489  glEnd();
490  glEnable(GL_LIGHTING); // Disable lights when drawing lines
491 
493  }
494 
495  // Optional post-Render user code:
496  if (hasSubscribers())
497  {
498  mrptEventGLPostRender ev(this);
499  this->publishEvent(ev);
500  }
501  }
502  catch (exception& e)
503  {
504  string msg;
505  if (it != nullptr)
506  msg = format(
507  "Exception while rendering a class '%s'\n%s",
508  it->GetRuntimeClass()->className, e.what());
509  else
510  msg = format("Exception while rendering:\n%s", e.what());
511 
512  THROW_EXCEPTION(msg);
513  }
514  catch (...)
515  {
516  THROW_EXCEPTION("Runtime error!");
517  }
518 #else
519  MRPT_UNUSED_PARAM(render_width);
520  MRPT_UNUSED_PARAM(render_height);
522  "The MRPT has been compiled with MRPT_HAS_OPENGL_GLUT=0! OpenGL "
523  "functions are not implemented");
524 #endif
525 }
526 
529 {
530  // Save data:
534 
535  // Added in v1:
538 
539  // Save objects:
540  uint32_t n;
541  n = (uint32_t)m_objects.size();
542  out << n;
543  for (const auto& m_object : m_objects) out << *m_object;
544 
545  // Added in v2: Global OpenGL settings:
547 
548  // Added in v3: Lights
549  out << m_lights;
550 }
551 
554 {
555  switch (version)
556  {
557  case 0:
558  case 1:
559  case 2:
560  case 3:
561  {
562  // Load data:
567 
568  // in v1:
569  if (version >= 1)
570  {
574  }
575  else
576  {
577  m_custom_backgb_color = false;
578  }
579 
580  // Load objects:
581  uint32_t n;
582  in >> n;
583  clear();
584  m_objects.resize(n);
585 
586  for_each(
587  m_objects.begin(), m_objects.end(), ObjectReadFromStream(&in));
588 
589  // Added in v2: Global OpenGL settings:
590  if (version >= 2)
591  {
593  }
594  else
595  {
596  // Defaults
597  }
598 
599  // Added in v3: Lights
600  if (version >= 3)
601  in >> m_lights;
602  else
603  {
604  // Default: one light from default direction
605  m_lights.clear();
606  m_lights.emplace_back();
607  }
608  }
609  break;
610  default:
612  };
613 }
614 
615 /*---------------------------------------------------------------
616  getByName
617  ---------------------------------------------------------------*/
619 {
620  for (auto& m_object : m_objects)
621  {
622  if (m_object->m_name == str)
623  return m_object;
624  else if (
625  m_object->GetRuntimeClass() ==
627  {
628  CRenderizable::Ptr ret =
629  std::dynamic_pointer_cast<CSetOfObjects>(m_object)->getByName(
630  str);
631  if (ret) return ret;
632  }
633  }
634  return CRenderizable::Ptr();
635 }
636 
637 /*---------------------------------------------------------------
638  initializeAllTextures
639  ---------------------------------------------------------------*/
641 {
642 #if MRPT_HAS_OPENGL_GLUT
643  for (auto& obj : m_objects)
644  {
646  std::dynamic_pointer_cast<CTexturedObject>(obj)
647  ->loadTextureInOpenGL();
648  else if (IS_CLASS(*obj, CSetOfObjects))
649  std::dynamic_pointer_cast<CSetOfObjects>(obj)
651  }
652 #endif
653 }
654 
655 void COpenGLViewport::dumpListOfObjects(std::vector<std::string>& lst)
656 {
657  for (auto& m_object : m_objects)
658  {
659  // Single obj:
660  string s(m_object->GetRuntimeClass()->className);
661  if (m_object->m_name.size())
662  s += string(" (") + m_object->m_name + string(")");
663  lst.emplace_back(s);
664 
665  if (m_object->GetRuntimeClass() ==
667  {
668  std::vector<std::string> auxLst;
669 
670  dynamic_cast<CSetOfObjects*>(m_object.get())
671  ->dumpListOfObjects(auxLst);
672 
673  for (const auto& i : auxLst) lst.emplace_back(string(" ") + i);
674  }
675  }
676 }
677 
678 /*--------------------------------------------------------------
679  removeObject
680  ---------------------------------------------------------------*/
682 {
683  for (auto it = m_objects.begin(); it != m_objects.end(); ++it)
684  if (*it == obj)
685  {
686  m_objects.erase(it);
687  return;
688  }
689  else if (
690  (*it)->GetRuntimeClass() ==
692  dynamic_cast<CSetOfObjects*>(it->get())->removeObject(obj);
693 }
694 
695 /*--------------------------------------------------------------
696  setViewportClipDistances
697  ---------------------------------------------------------------*/
699  const double clip_min, const double clip_max)
700 {
701  ASSERT_(clip_max > clip_min);
702 
703  m_clip_min = clip_min;
704  m_clip_max = clip_max;
705 }
706 
707 /*--------------------------------------------------------------
708  getViewportClipDistances
709  ---------------------------------------------------------------*/
711  double& clip_min, double& clip_max) const
712 {
713  clip_min = m_clip_min;
714  clip_max = m_clip_max;
715 }
716 
717 /*--------------------------------------------------------------
718  get3DRayForPixelCoord
719  ---------------------------------------------------------------*/
721  const double x_coord, const double y_coord, mrpt::math::TLine3D& out_ray,
722  mrpt::poses::CPose3D* out_cameraPose) const
723 {
724  ASSERTDEB_(
726 
727  const double ASPECT =
729 
730  // unitary vector between (eye) -> (pointing):
731  TPoint3D pointing_dir;
732  pointing_dir.x = -cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
733  pointing_dir.y = -sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
734  pointing_dir.z = -sin(m_lastProjMat.elev);
735 
736  // The camera X vector (in 3D) can be computed from the camera azimuth
737  // angle:
738  TPoint3D cam_x_3d;
739  cam_x_3d.x = -sin(m_lastProjMat.azimuth);
740  cam_x_3d.y = cos(m_lastProjMat.azimuth);
741  cam_x_3d.z = 0;
742 
743  // The camera real UP vector (in 3D) is the cross product:
744  // X3d x pointing_dir:
745  TPoint3D cam_up_3d;
746  crossProduct3D(cam_x_3d, pointing_dir, cam_up_3d);
747 
749  {
750  // Ortho projection:
751  // -------------------------------
752  double Ax = m_lastProjMat.zoom * 0.5;
753  double Ay = Ax;
754 
755  if (ASPECT > 1)
756  Ax *= ASPECT;
757  else
758  {
759  if (ASPECT != 0) Ay /= ASPECT;
760  }
761 
762  const double point_lx =
763  (-0.5 + x_coord / m_lastProjMat.viewport_width) * 2 * Ax;
764  const double point_ly =
765  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * 2 * Ay;
766 
767  const TPoint3D ray_origin(
768  m_lastProjMat.eye.x + point_lx * cam_x_3d.x +
769  point_ly * cam_up_3d.x,
770  m_lastProjMat.eye.y + point_lx * cam_x_3d.y +
771  point_ly * cam_up_3d.y,
772  m_lastProjMat.eye.z + point_lx * cam_x_3d.z +
773  point_ly * cam_up_3d.z);
774 
775  out_ray.pBase = ray_origin;
776  out_ray.director[0] = pointing_dir.x;
777  out_ray.director[1] = pointing_dir.y;
778  out_ray.director[2] = pointing_dir.z;
779  }
780  else
781  {
782  // Perspective camera
783  // -------------------------------
784 
785  // JL: This can derived from:
786  // http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml
787  // where one arrives to:
788  // tan(FOVx/2) = ASPECT_RATIO * tan(FOVy/2)
789  //
790  const double FOVy = DEG2RAD(m_lastProjMat.FOV);
791  const double FOVx = 2.0 * atan(ASPECT * tan(FOVy * 0.5));
792 
793  const double ang_horz =
794  (-0.5 + x_coord / m_lastProjMat.viewport_width) * FOVx;
795  const double ang_vert =
796  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * FOVy;
797 
798  const TPoint3D l(
799  tan(ang_horz), tan(ang_vert),
800  1.0); // Point in camera local reference frame
801 
802  const TPoint3D ray_director(
803  l.x * cam_x_3d.x + l.y * cam_up_3d.x + l.z * pointing_dir.x,
804  l.x * cam_x_3d.y + l.y * cam_up_3d.y + l.z * pointing_dir.y,
805  l.x * cam_x_3d.z + l.y * cam_up_3d.z + l.z * pointing_dir.z);
806 
807  // Set out ray:
808  out_ray.pBase = m_lastProjMat.eye;
809  out_ray.director[0] = ray_director.x;
810  out_ray.director[1] = ray_director.y;
811  out_ray.director[2] = ray_director.z;
812 
813  } // end projective
814 
815  // Camera pose:
816  if (out_cameraPose)
817  {
819  M(0, 0) = cam_x_3d.x;
820  M(1, 0) = cam_x_3d.y;
821  M(2, 0) = cam_x_3d.z;
822  M(3, 0) = 0;
823 
824  M(0, 1) = cam_up_3d.x;
825  M(1, 1) = cam_up_3d.y;
826  M(2, 1) = cam_up_3d.z;
827  M(3, 1) = 0;
828 
829  M(0, 2) = pointing_dir.x;
830  M(1, 2) = pointing_dir.y;
831  M(2, 2) = pointing_dir.z;
832  M(3, 2) = 0;
833 
834  M(0, 3) = m_lastProjMat.eye.x;
835  M(1, 3) = m_lastProjMat.eye.y;
836  M(2, 3) = m_lastProjMat.eye.z;
837  M(3, 3) = 1;
838 
839  *out_cameraPose = CPose3D(M);
840  }
841 }
842 
843 MRPT_TODO("Implement a setCurrentCameraFromPose() method")
844 
845 void COpenGLViewport::getCurrentCameraPose(
846  mrpt::poses::CPose3D& out_cameraPose) const
847 {
849  get3DRayForPixelCoord(0, 0, dum, &out_cameraPose);
850 }
851 
852 /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView
853  */
855 {
856  // If this was a m_isImageView, remove the quad object:
858 
859  m_isCloned = false;
860  m_isClonedCamera = false;
861  m_isImageView = false;
862 }
863 
865 {
867  *m_imageview_img = img;
868 }
870 {
872  *m_imageview_img = std::move(img);
873 }
874 
876 {
877  // If this is the first time, we have to create the quad object:
880  m_isImageView = true;
881 }
882 
883 /** Evaluates the bounding box of this object (including possible children) in
884  * the coordinate frame of the object parent. */
887 {
888  bb_min = TPoint3D(
889  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
890  std::numeric_limits<double>::max());
891  bb_max = TPoint3D(
892  -std::numeric_limits<double>::max(),
893  -std::numeric_limits<double>::max(),
894  -std::numeric_limits<double>::max());
895 
896  for (const auto& m_object : m_objects)
897  {
898  TPoint3D child_bbmin(
899  std::numeric_limits<double>::max(),
900  std::numeric_limits<double>::max(),
901  std::numeric_limits<double>::max());
902  TPoint3D child_bbmax(
903  -std::numeric_limits<double>::max(),
904  -std::numeric_limits<double>::max(),
905  -std::numeric_limits<double>::max());
906  m_object->getBoundingBox(child_bbmin, child_bbmax);
907 
908  keep_min(bb_min.x, child_bbmin.x);
909  keep_min(bb_min.y, child_bbmin.y);
910  keep_min(bb_min.z, child_bbmin.z);
911 
912  keep_max(bb_max.x, child_bbmax.x);
913  keep_max(bb_max.y, child_bbmax.y);
914  keep_max(bb_max.z, child_bbmax.z);
915  }
916 }
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.
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
#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
double DEG2RAD(const double x)
Degrees to radians.
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
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...
#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
unsigned char uint8_t
Definition: rptypes.h:44
#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 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...
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
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:138
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:133
#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)
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.
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:92
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:53
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:84
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
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
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:48
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:224
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
unsigned __int32 uint32_t
Definition: rptypes.h:50
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: c26d46ba6 Thu Jul 18 13:03:42 2019 +0200 at jue jul 18 13:10:17 CEST 2019