MRPT  2.0.4
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-2020, 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>
13 #include <mrpt/math/geometry.h> // crossProduct3D()
23 #include <Eigen/Dense>
24 
25 #include <mrpt/opengl/opengl_api.h>
26 
27 using namespace mrpt;
28 using namespace mrpt::poses;
29 using namespace mrpt::opengl;
30 using namespace mrpt::math;
32 using namespace std;
33 
35 
36 //#define OPENGLVIEWPORT_ENABLE_TIMEPROFILING
37 
38 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
39 mrpt::system::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_parent(parent), m_name(name)
53 {
54 }
55 
57 
58 void COpenGLViewport::setCloneView(const string& clonedViewport)
59 {
60  clear();
61  m_isCloned = true;
62  m_clonedViewport = clonedViewport;
63 }
64 
66  const double x, const double y, const double width, const double height)
67 {
69  ASSERT_(m_view_width > 0);
71 
72  m_view_x = x;
73  m_view_y = y;
74  m_view_width = width;
75  m_view_height = height;
76 
77  MRPT_END
78 }
79 
80 /*--------------------------------------------------------------
81  getViewportPosition
82  ---------------------------------------------------------------*/
84  double& x, double& y, double& width, double& height)
85 {
86  x = m_view_x;
87  y = m_view_y;
88  width = m_view_width;
89  height = m_view_height;
90 }
91 
92 /*--------------------------------------------------------------
93  clear
94  ---------------------------------------------------------------*/
95 void COpenGLViewport::clear() { m_objects.clear(); }
96 /*--------------------------------------------------------------
97  insert
98  ---------------------------------------------------------------*/
100 {
101  m_objects.push_back(newObject);
102 }
103 
104 // Maps [0,1] to [0,Len], wrap negative numbers, etc.
105 static int sizeFromRatio(
106  const int startCoord, const double dSize, const int iLength)
107 {
108  if (dSize > 1) // >1 -> absolute pixels:
109  return static_cast<int>(dSize);
110  else if (dSize < 0)
111  { // Negative numbers: Specify the right side coordinates instead of
112  // the width:
113  if (dSize >= -1)
114  return static_cast<int>(-iLength * dSize - startCoord + 1);
115  else
116  return static_cast<int>(-dSize - startCoord + 1);
117  }
118  // Otherwise: a fraction
119  return static_cast<int>(iLength * dSize);
120 }
121 static int startFromRatio(const double frac, const int dSize)
122 {
123  return frac > 1 ? static_cast<int>(frac)
124  : (frac < 0 ? static_cast<int>(dSize + frac)
125  : static_cast<int>(dSize * frac));
126 }
127 
128 // "Image mode" rendering:
130 {
131 #if MRPT_HAS_OPENGL_GLUT
132 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
134  glv_timlog, "COpenGLViewport::render imageview");
135 #endif
136 
137  // Do we have an actual image to render?
138  if (!m_imageview_plane) return;
139 
140  auto _ = m_state;
141 
142  glDisable(GL_DEPTH_TEST);
143  glEnable(GL_BLEND);
144  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
145 
146  // Adjust the aspect ratio:
147  const auto img_w = m_imageview_plane->getTextureImage().getWidth();
148  const auto img_h = m_imageview_plane->getTextureImage().getHeight();
149  const double img_ratio = double(img_w) / img_h;
150  const double vw_ratio = double(_.viewport_width) / _.viewport_height;
151  const double ratio = vw_ratio / img_ratio;
152 
153  _.mv_matrix.setIdentity();
154  _.p_matrix.setIdentity();
155 
156  if (img_ratio > 1)
157  _.p_matrix(1, 1) /= img_ratio;
158  else if (img_ratio > 0)
159  _.p_matrix(0, 0) /= img_ratio;
160 
161  if (ratio > 0) _.p_matrix(0, 0) /= ratio;
162 
163  auto &p00 = _.p_matrix(0, 0), &p11 = _.p_matrix(1, 1);
164  if (p00 > 0 && p11 > 0)
165  {
166  const double s = (p00 > p11) ? p00 : p11;
167  p00 /= s;
168  p11 /= s;
169  }
170 
171  _.pmv_matrix.asEigen() = _.p_matrix.asEigen() * _.mv_matrix.asEigen();
172 
173  // Pass 1: Process all objects (recursively for sets of objects):
174  CListOpenGLObjects lst;
175  lst.push_back(m_imageview_plane);
178 
179  // pass 2: render, sorted by shader program:
181 
182 #endif
183 }
184 
186 
188 {
189 #if MRPT_HAS_OPENGL_GLUT
190  MRPT_START
191 
192  std::vector<shader_id_t> lstShaderIDs = {
196 
197  for (const auto& id : lstShaderIDs)
198  {
200 
201  ASSERT_(m_shaders[id]);
202  ASSERT_(!m_shaders[id]->empty());
203  }
204 
205  MRPT_END
206 #endif
207 }
208 
209 /** Render a normal scene with 3D objects */
211 {
212 #if MRPT_HAS_OPENGL_GLUT
213  MRPT_START
214 
215  // Prepare camera (projection matrix):
216  const CListOpenGLObjects* objectsToRender = nullptr;
217  COpenGLViewport* viewForGetCamera = nullptr;
218 
219  if (m_isCloned)
220  { // Clone: render someone's else objects.
221  ASSERT_(m_parent.get() != nullptr);
222 
223  COpenGLViewport::Ptr view = m_parent->getViewport(m_clonedViewport);
224  if (!view)
226  "Cloned viewport '%s' not found in parent COpenGLScene",
227  m_clonedViewport.c_str());
228 
229  objectsToRender = &view->m_objects;
230  viewForGetCamera =
231  m_isClonedCamera ? view.get() : const_cast<COpenGLViewport*>(this);
232  }
233  else
234  { // Normal case: render our own objects:
235  objectsToRender = &m_objects;
236  viewForGetCamera = const_cast<COpenGLViewport*>(this);
237  }
238 
239  // Get camera:
240  // 1st: if there is a CCamera in the scene (nullptr if no camera found):
241  const CCamera* myCamera =
242  dynamic_cast<CCamera*>(viewForGetCamera->getByClass<CCamera>().get());
243 
244  // 2nd: the internal camera of all viewports:
245  if (!myCamera) myCamera = &viewForGetCamera->m_camera;
246 
248 
249  auto& _ = m_state;
250 
251  _.is_projective = myCamera->m_projectiveModel;
252  _.FOV = myCamera->m_projectiveFOVdeg;
253  _.eyeDistance = myCamera->m_eyeDistance;
254  _.azimuth = DEG2RAD(myCamera->m_azimuthDeg);
255  _.elev = DEG2RAD(myCamera->m_elevationDeg);
256 
257  if (myCamera->is6DOFMode())
258  {
259  // In 6DOFMode eye is set viewing towards the direction of the
260  // positive Z axis
261  // Up is set as Y axis
262  mrpt::poses::CPose3D viewDirection, pose, at;
263  viewDirection.x(+1);
264  pose = mrpt::poses::CPose3D(myCamera->getPose());
265  at = pose + viewDirection;
266 
267  _.eye.x = pose.x();
268  _.eye.y = pose.y();
269  _.eye.z = pose.z();
270  _.pointing.x = at.x();
271  _.pointing.y = at.y();
272  _.pointing.z = at.z();
273  _.up.x = pose.getRotationMatrix()(0, 2);
274  _.up.y = pose.getRotationMatrix()(1, 2);
275  _.up.z = pose.getRotationMatrix()(2, 2);
276  }
277  else
278  {
279  // Normal mode: use "camera orbit" parameters to compute pointing-to
280  // point:
281  const double dis = std::max<double>(0.005, myCamera->m_eyeDistance);
282  _.eye.x = _.pointing.x + dis * cos(_.azimuth) * cos(_.elev);
283  _.eye.y = _.pointing.y + dis * sin(_.azimuth) * cos(_.elev);
284  _.eye.z = _.pointing.z + dis * sin(_.elev);
285 
286  _.pointing.x = myCamera->m_pointingX;
287  _.pointing.y = myCamera->m_pointingY;
288  _.pointing.z = myCamera->m_pointingZ;
289 
290  _.up.x = -cos(_.azimuth) * sin(_.elev);
291  _.up.y = -sin(_.azimuth) * sin(_.elev);
292  _.up.z = cos(_.elev);
293  }
294 
295  // Compute the projection matrix (p_matrix):
296  _.computeProjectionMatrix(m_clip_min, m_clip_max);
297 
298  // Apply eye center and lookAt to p_matrix:
299  _.applyLookAt();
300 
301  // Optional pre-Render user code:
302  if (hasSubscribers())
303  {
304  mrptEventGLPreRender ev(this);
305  this->publishEvent(ev);
306  }
307 
308  // Global OpenGL settings:
309  // ---------------------------------
310  glHint(
311  GL_POLYGON_SMOOTH_HINT,
312  m_OpenGL_enablePolygonNicest ? GL_NICEST : GL_FASTEST);
313  CHECK_OPENGL_ERROR();
314 
315  // Reset model-view 4x4 matrix to the identity transformation:
316  _.mv_matrix.setIdentity();
317 
318  glEnable(GL_DEPTH_TEST);
319  glDepthFunc(GL_LEQUAL); // GL_LESS
320 
321  glEnable(GL_BLEND);
322  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
323 
324 // Enable point sizes>1
325 #if defined(GL_PROGRAM_POINT_SIZE) // it seems it's undefined in OSX (?)
326  glEnable(GL_PROGRAM_POINT_SIZE);
327  CHECK_OPENGL_ERROR();
328 #endif
329 
330  // Pass 1: Process all objects (recursively for sets of objects):
332  mrpt::opengl::enqueForRendering(*objectsToRender, _, rq);
333 
334  // pass 2: render, sorted by shader program:
336 
337  MRPT_END
338 
339 #endif
340 }
341 
343 {
344 #if MRPT_HAS_OPENGL_GLUT
345  MRPT_START
346  if (m_borderWidth < 1) return;
347 
348  auto _ = m_state;
349 
351  _.p_matrix.setIdentity();
352  _.pmv_matrix.setIdentity();
353 
354  glDisable(GL_DEPTH_TEST);
355  glEnable(GL_BLEND);
356  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
357 
358  //
359  if (!m_borderLines)
360  {
362  m_borderLines->appendLine(-1, -1, 0, -1, 1, 0);
363  m_borderLines->appendLine(-1, 1, 0, 1, 1, 0);
364  m_borderLines->appendLine(1, 1, 0, 1, -1, 0);
365  m_borderLines->appendLine(1, -1, 0, -1, -1, 0);
366  }
367  m_borderLines->setLineWidth(m_borderWidth);
368  m_borderLines->setColor_u8(m_borderColor);
369 
370  CListOpenGLObjects lst;
371  lst.push_back(m_borderLines);
372 
373  // Pass 1: Process all objects (recursively for sets of objects):
376 
377  // pass 2: render, sorted by shader program:
379  MRPT_END
380 #endif
381 }
382 
384 {
385 #if MRPT_HAS_OPENGL_GLUT
386  MRPT_START
387 
388  // Ensure GL objects are up-to-date:
390 
391  // Prepare shaders upon first invokation:
392  if (m_shaders.empty()) loadDefaultShaders();
393 
394  // Prepare camera (projection matrix):
395  TRenderMatrices _ = m_state; // make a copy
396 
397  // Compute the projection matrix (p_matrix):
398  // was: glLoadIdentity(); glOrtho(0, w, 0, h, -1, 1);
399  const auto w = _.viewport_width, h = _.viewport_height;
400  _.is_projective = false;
401 
402  _.p_matrix.setIdentity();
403  //_.computeOrthoProjectionMatrix(0, w, 0, h, m_clip_min, m_clip_max);
404 
405  // Reset model-view 4x4 matrix to the identity transformation:
407 
408  // glDisable(GL_DEPTH_TEST);
409  glEnable(GL_BLEND);
410  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
411 
412  // Collect all 2D text objects, and update their properties:
413  CListOpenGLObjects objs;
414  for (auto& kv : m_2D_texts.messages)
415  {
416  const DataPerText& label = kv.second;
417 
418  // If (x,y) \in [0,1[, it's interpreted as a ratio, otherwise, as an
419  // actual coordinate in pixels
420  float x =
421  label.x >= 1 ? label.x : (label.x < 0 ? w + label.x : label.x * w);
422  float y =
423  label.y >= 1 ? label.y : (label.y < 0 ? h + label.y : label.y * h);
424 
425  if (CText::Ptr& o = label.gl_text; o)
426  {
427  o->setFont(label.vfont_name, label.vfont_scale * 2);
428  o->setString(label.text);
429  o->setColor(label.color);
430  // Change coordinates: mrpt text (0,0)-(1,1) to OpenGL
431  // (-1,-1)-(+1,+1):
432  o->setLocation(-1.0f + 2 * x / w, -1.0f + 2 * y / h, 0);
433  objs.push_back(o);
434  }
435  if (CText::Ptr& o = label.gl_text_shadow; o)
436  {
437  o->setFont(label.vfont_name, label.vfont_scale * 2);
438  o->setString(label.text);
439  o->setColor(label.shadow_color);
440  // Change coordinates: mrpt text (0,0)-(1,1) to OpenGL
441  // (-1,-1)-(+1,+1):
442  o->setLocation(
443  -1.0f + 2 * (x + 1) / w, -1.0f + 2 * (y - 1) / h, 0.1);
444  objs.push_back(o);
445  }
446  }
447 
448  // Pass 1: Process all objects (recursively for sets of objects):
450  mrpt::opengl::enqueForRendering(objs, _, rq);
451 
452  // pass 2: render, sorted by shader program:
454  MRPT_END
455 #endif
456 }
457 
459  [[maybe_unused]] const int render_width,
460  [[maybe_unused]] const int render_height,
461  [[maybe_unused]] const int render_offset_x,
462  [[maybe_unused]] const int render_offset_y) const
463 {
464 #if MRPT_HAS_OPENGL_GLUT
465  MRPT_START
466 
467  // Change viewport:
468  // -------------------------------------------
469  const GLint vx = render_offset_x + startFromRatio(m_view_x, render_width);
470  const GLint vy = render_offset_y + startFromRatio(m_view_y, render_height);
471  const GLint vw = sizeFromRatio(vx, m_view_width, render_width);
472  const GLint vh = sizeFromRatio(vy, m_view_height, render_height);
473 
474  glViewport(vx, vy, vw, vh);
475  CHECK_OPENGL_ERROR();
476 
477  // Clear depth&/color buffers:
478  // -------------------------------------------
479  m_state.viewport_width = vw;
481 
482  glScissor(vx, vy, vw, vh);
483  CHECK_OPENGL_ERROR();
484 
485  glEnable(GL_SCISSOR_TEST);
486  CHECK_OPENGL_ERROR();
487 
488  if (!m_isTransparent)
489  { // Clear color & depth buffers:
490  // Save?
491 
492  GLclampf prevCol[4];
494  {
495  glGetFloatv(GL_COLOR_CLEAR_VALUE, prevCol);
496  CHECK_OPENGL_ERROR();
497  glClearColor(
500  CHECK_OPENGL_ERROR();
501  }
502 
503  glClear(
504  GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
505  CHECK_OPENGL_ERROR();
506 
507  // Restore old colors:
509  {
510  glClearColor(prevCol[0], prevCol[1], prevCol[2], prevCol[3]);
511  CHECK_OPENGL_ERROR();
512  }
513  }
514  else
515  { // Clear depth buffer only:
516  glClear(GL_DEPTH_BUFFER_BIT);
517  CHECK_OPENGL_ERROR();
518  }
519  glDisable(GL_SCISSOR_TEST);
520  CHECK_OPENGL_ERROR();
521 
522  // Prepare shaders upon first invokation:
523  if (m_shaders.empty()) loadDefaultShaders();
524 
525  // If we are in "image mode", rendering is much simpler: just set
526  // ortho projection and render the image quad:
527  if (m_isImageView)
528  renderImageMode();
529  else
531 
532  // Draw text messages, if any:
534 
535  // Finally, draw the border:
537 
538  // Optional post-Render user code:
539  if (hasSubscribers())
540  {
541  mrptEventGLPostRender ev(this);
542  this->publishEvent(ev);
543  }
544 
545  MRPT_END
546 #else
548  "The MRPT has been compiled with MRPT_HAS_OPENGL_GLUT=0! OpenGL "
549  "functions are not implemented");
550 #endif
551 }
552 
553 uint8_t COpenGLViewport::serializeGetVersion() const { return 3; }
555 {
556  // Save data:
560 
561  // Added in v1:
564 
565  // Save objects:
566  uint32_t n;
567  n = (uint32_t)m_objects.size();
568  out << n;
569  for (const auto& m_object : m_objects) out << *m_object;
570 
571  // Added in v2: Global OpenGL settings:
573 
574  // Added in v3: Lights
575  out << m_lights;
576 }
577 
579  mrpt::serialization::CArchive& in, uint8_t version)
580 {
581  switch (version)
582  {
583  case 0:
584  case 1:
585  case 2:
586  case 3:
587  {
588  // Load data:
589  in >> m_camera >> m_isCloned >> m_isClonedCamera >>
593 
594  // in v1:
595  if (version >= 1)
596  {
600  }
601  else
602  {
603  m_custom_backgb_color = false;
604  }
605 
606  // Load objects:
607  uint32_t n;
608  in >> n;
609  clear();
610  m_objects.resize(n);
611 
612  for_each(
613  m_objects.begin(), m_objects.end(), ObjectReadFromStream(&in));
614 
615  // Added in v2: Global OpenGL settings:
616  if (version >= 2)
617  {
619  }
620  else
621  {
622  // Defaults
623  }
624 
625  // Added in v3: Lights
626  if (version >= 3)
627  in >> m_lights;
628  else
629  {
630  // Default:
632  }
633  }
634  break;
635  default:
637  };
638 }
639 
640 /*---------------------------------------------------------------
641  getByName
642  ---------------------------------------------------------------*/
644 {
645  for (auto& m_object : m_objects)
646  {
647  if (m_object->m_name == str)
648  return m_object;
649  else if (
650  m_object->GetRuntimeClass() ==
652  {
653  CRenderizable::Ptr ret =
654  std::dynamic_pointer_cast<CSetOfObjects>(m_object)->getByName(
655  str);
656  if (ret) return ret;
657  }
658  }
659  return CRenderizable::Ptr();
660 }
661 
663 {
664  for (auto& obj : m_objects) obj->initializeTextures();
665 }
666 
667 void COpenGLViewport::dumpListOfObjects(std::vector<std::string>& lst)
668 {
669  for (auto& m_object : m_objects)
670  {
671  // Single obj:
672  string s(m_object->GetRuntimeClass()->className);
673  if (m_object->m_name.size())
674  s += string(" (") + m_object->m_name + string(")");
675  lst.emplace_back(s);
676 
677  if (m_object->GetRuntimeClass() ==
679  {
680  std::vector<std::string> auxLst;
681 
682  dynamic_cast<CSetOfObjects*>(m_object.get())
683  ->dumpListOfObjects(auxLst);
684 
685  for (const auto& i : auxLst) lst.emplace_back(string(" ") + i);
686  }
687  }
688 }
689 
690 /*--------------------------------------------------------------
691  removeObject
692  ---------------------------------------------------------------*/
694 {
695  for (auto it = m_objects.begin(); it != m_objects.end(); ++it)
696  if (*it == obj)
697  {
698  m_objects.erase(it);
699  return;
700  }
701  else if (
702  (*it)->GetRuntimeClass() ==
704  dynamic_cast<CSetOfObjects*>(it->get())->removeObject(obj);
705 }
706 
708  const float clip_min, const float clip_max)
709 {
710  ASSERT_ABOVE_(clip_max, clip_min);
711 
712  m_clip_min = clip_min;
713  m_clip_max = clip_max;
714 }
715 
717  float& clip_min, float& clip_max) const
718 {
719  clip_min = m_clip_min;
720  clip_max = m_clip_max;
721 }
722 
723 /*--------------------------------------------------------------
724  get3DRayForPixelCoord
725  ---------------------------------------------------------------*/
727  const double x_coord, const double y_coord, mrpt::math::TLine3D& out_ray,
728  mrpt::poses::CPose3D* out_cameraPose) const
729 {
731 
732  const double ASPECT =
734 
735  // unitary vector between (eye) -> (pointing):
736  TPoint3D pointing_dir;
737  pointing_dir.x = -cos(m_state.azimuth) * cos(m_state.elev);
738  pointing_dir.y = -sin(m_state.azimuth) * cos(m_state.elev);
739  pointing_dir.z = -sin(m_state.elev);
740 
741  // The camera X vector (in 3D) can be computed from the camera azimuth
742  // angle:
743  TPoint3D cam_x_3d;
744  cam_x_3d.x = -sin(m_state.azimuth);
745  cam_x_3d.y = cos(m_state.azimuth);
746  cam_x_3d.z = 0;
747 
748  // The camera real UP vector (in 3D) is the cross product:
749  // X3d x pointing_dir:
750  TPoint3D cam_up_3d;
751  mrpt::math::crossProduct3D(cam_x_3d, pointing_dir, cam_up_3d);
752 
753  if (!m_state.is_projective)
754  {
755  // Ortho projection:
756  // -------------------------------
757  double Ax = m_state.eyeDistance * 0.5;
758  double Ay = Ax;
759 
760  if (ASPECT > 1)
761  Ax *= ASPECT;
762  else
763  {
764  if (ASPECT != 0) Ay /= ASPECT;
765  }
766 
767  const double point_lx =
768  (-0.5 + x_coord / m_state.viewport_width) * 2 * Ax;
769  const double point_ly =
770  -(-0.5 + y_coord / m_state.viewport_height) * 2 * Ay;
771 
772  const TPoint3D ray_origin(
773  m_state.eye.x + point_lx * cam_x_3d.x + point_ly * cam_up_3d.x,
774  m_state.eye.y + point_lx * cam_x_3d.y + point_ly * cam_up_3d.y,
775  m_state.eye.z + point_lx * cam_x_3d.z + point_ly * cam_up_3d.z);
776 
777  out_ray.pBase = ray_origin;
778  out_ray.director[0] = pointing_dir.x;
779  out_ray.director[1] = pointing_dir.y;
780  out_ray.director[2] = pointing_dir.z;
781  }
782  else
783  {
784  // Perspective camera
785  // -------------------------------
786 
787  // JL: This can be derived from:
788  // http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml
789  // where one arrives to:
790  // tan(FOVx/2) = ASPECT_RATIO * tan(FOVy/2)
791  //
792  const double FOVy = DEG2RAD(m_state.FOV);
793  const double FOVx = 2.0 * atan(ASPECT * tan(FOVy * 0.5));
794 
795  const auto vw = m_state.viewport_width;
796  const auto vh = m_state.viewport_height;
797  const double len_horz = 2.0 * (-0.5 + x_coord / vw) * tan(0.5 * FOVx);
798  const double len_vert = -2.0 * (-0.5 + y_coord / vh) * tan(0.5 * FOVy);
799  // Point in camera local reference frame
800  const auto l = mrpt::math::TPoint3D(len_horz, len_vert, 1.0);
801 
802  const mrpt::math::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_state.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_state.eye.x;
835  M(1, 3) = m_state.eye.y;
836  M(2, 3) = m_state.eye.z;
837  M(3, 3) = 1;
838 
839  *out_cameraPose = CPose3D(M);
840  }
841 }
842 
844 {
845  m_camera.set6DOFMode(true);
846  m_camera.setPose(p);
847 }
848 
850  mrpt::poses::CPose3D& out_cameraPose) const
851 {
853  get3DRayForPixelCoord(0, 0, dum, &out_cameraPose);
854 }
855 
856 /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView
857  */
859 {
860  // If this was a m_isImageView, remove the quad object:
861  m_imageview_plane.reset();
862 
863  m_isCloned = false;
864  m_isClonedCamera = false;
865  m_isImageView = false;
866 }
867 
869 {
871  m_imageview_plane->assignImage(img);
872 }
874 {
876  m_imageview_plane->assignImage(img);
877 }
878 
880 {
881  // If this is the first time, we have to create the quad object:
882  if (!m_imageview_plane)
883  {
885  // Flip vertically:
886  m_imageview_plane->setPlaneCorners(-1, 1, 1, -1);
887  }
888  m_isImageView = true;
889 }
890 
891 /** Evaluates the bounding box of this object (including possible children) in
892  * the coordinate frame of the object parent. */
895 {
896  bb_min = TPoint3D(
897  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
898  std::numeric_limits<double>::max());
899  bb_max = TPoint3D(
900  -std::numeric_limits<double>::max(),
901  -std::numeric_limits<double>::max(),
902  -std::numeric_limits<double>::max());
903 
904  for (const auto& m_object : m_objects)
905  {
906  TPoint3D child_bbmin(
907  std::numeric_limits<double>::max(),
908  std::numeric_limits<double>::max(),
909  std::numeric_limits<double>::max());
910  TPoint3D child_bbmax(
911  -std::numeric_limits<double>::max(),
912  -std::numeric_limits<double>::max(),
913  -std::numeric_limits<double>::max());
914  m_object->getBoundingBox(child_bbmin, child_bbmax);
915 
916  keep_min(bb_min.x, child_bbmin.x);
917  keep_min(bb_min.y, child_bbmin.y);
918  keep_min(bb_min.z, child_bbmin.z);
919 
920  keep_max(bb_max.x, child_bbmax.x);
921  keep_max(bb_max.y, child_bbmax.y);
922  keep_max(bb_max.z, child_bbmax.z);
923  }
924 }
float m_projectiveFOVdeg
Field-of-View in degs, only when projectiveModel=true (default=30 deg).
Definition: CCamera.h:115
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
static int startFromRatio(const double frac, const int dSize)
float m_clip_min
The min/max clip depth distances (default: 0.1 - 10000)
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...
static Ptr Create(Args &&... args)
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
bool m_isTransparent
Whether to clear color buffer.
static constexpr shader_id_t TEXTURED_TRIANGLES
mrpt::opengl::CTexturedPlane::Ptr m_imageview_plane
The image to display, after calling setImageView()
A set of object, which are referenced to the coordinates framework established in this object...
Definition: CSetOfObjects.h:26
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
uint32_t m_borderWidth
Default=0, the border around the viewport.
A safe way to call enter() and leave() of a mrpt::system::CTimeLogger upon construction and destructi...
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.
void setViewportClipDistances(const float clip_min, const float clip_max)
Set the min/max clip depth distances of the rendering frustum (default: 0.1 - 10000) ...
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
std::deque< CRenderizable::Ptr > CListOpenGLObjects
A list of smart pointers to renderizable objects.
void set6DOFMode(bool v)
Set 6DOFMode, if enabled camera is set according to its pose (default=false).
Definition: CCamera.h:80
void processRenderQueue(const RenderQueue &rq, std::map< shader_id_t, mrpt::opengl::Program::Ptr > &shaders, const mrpt::opengl::TLightParameters &lights)
After enqueForRendering(), actually executes the rendering tasks, grouped shader by shader...
void setImageView(const mrpt::img::CImage &img)
Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport a...
void renderImageMode() const
Render in image mode.
std::shared_ptr< CRenderizable > Ptr
Definition: CRenderizable.h:50
static constexpr shader_id_t TEXT
TPoint3D pBase
Base point.
Definition: TLine3D.h:23
STL namespace.
A viewport within a COpenGLScene, containing a set of OpenGL objects to render.
void getViewportClipDistances(float &clip_min, float &clip_max) const
Get the current min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
mrpt::safe_ptr< COpenGLScene > m_parent
The scene that contains this viewport.
TRenderMatrices m_state
Info updated with each "render()" and used in "get3DRayForPixelCoord".
void loadDefaultShaders() const
Load all MPRT predefined shader programs into m_shaders.
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:765
std::string vfont_name
Vectorized font name ("sans","mono","serif")
Definition: opengl_fonts.h:41
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:97
bool m_isClonedCamera
Set by setCloneCamera.
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
This base provides a set of functions for maths stuff.
bool m_isImageView
Set by setImageView.
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...
std::array< double, 3 > director
Director vector.
Definition: TLine3D.h:25
void enqueForRendering(const mrpt::opengl::CListOpenGLObjects &objs, const mrpt::opengl::TRenderMatrices &state, RenderQueue &rq)
Processes, recursively, all objects in the list, classifying them by shader programs into a list suit...
Definition: RenderQueue.cpp:28
static int sizeFromRatio(const int startCoord, const double dSize, const int iLength)
constexpr double DEG2RAD(const double x)
Degrees to radians.
static constexpr shader_id_t WIREFRAME
void render(const int render_width, const int render_height, const int render_offset_x=0, const int render_offset_y=0) const
Render the objects in this viewport (called from COpenGLScene)
~COpenGLViewport() override
Destructor: clears all objects.
void unloadShaders()
Unload shader programs in m_shaders.
void removeObject(const CRenderizable::Ptr &obj)
Removes the given object from the scene (it also deletes the object to free its memory).
TPoint3D_< double > TPoint3D
Lightweight 3D point.
Definition: TPoint3D.h:268
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:143
void setNormalMode()
Resets the viewport to a normal 3D viewport.
mrpt::math::CMatrixFloat44 mv_matrix
Model-view matrix.
Rendering state related to the projection and model-view matrices.
void getCurrentCameraPose(mrpt::poses::CPose3D &out_cameraPose) const
Compute the current 3D camera pose.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
double azimuth
Camera elev & azimuth, in radians.
static constexpr shader_id_t TRIANGLES
void renderTextMessages() const
Renders all messages in the underlying class CTextMessageCapable.
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...
#define CLASS_ID_NAMESPACE(class_name, namespaceName)
Definition: CObject.h:105
T x
X,Y,Z coordinates.
Definition: TPoint3D.h:29
std::map< shader_id_t, mrpt::opengl::Program::Ptr > m_shaders
Default shader program.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool m_projectiveModel
If set to true (default), camera model is projective, otherwise, it&#39;s orthogonal. ...
Definition: CCamera.h:112
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:54
void clear()
Delete all internal obejcts.
size_t viewport_width
In pixels.
mrpt::math::TPoint3D eye
The camera is here.
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.
void regenerateGLobjects() const
(re)generate all CText objects in the gl_text fields
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
void initializeTextures()
Initializes all textures in the scene (See opengl::CTexturedPlane::initializeTextures) ...
Program::Ptr LoadDefaultShader(const shader_id_t id)
Loads a set of OpenGL Vertex+Fragment shaders from the default library available in mrpt::opengl...
An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives a...
#define ASSERT_ABOVE_(__A, __B)
Definition: exceptions.h:155
#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
mrpt::opengl::CSetOfLines::Ptr m_borderLines
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:56
const auto bb_max
std::string m_clonedViewport
Only if m_isCloned=true.
CRenderizable & setPose(const mrpt::poses::CPose3D &o)
Set the 3D pose from a mrpt::poses::CPose3D object (return a ref to this)
mrpt::img::TColorf m_background_color
used only if m_custom_backgb_color
void renderNormalSceneMode() const
Render a normal scene with 3D objects.
mrpt::img::TColorf color
Definition: opengl_fonts.h:46
const auto bb_min
double FOV
Vertical FOV in degrees.
mrpt::math::CMatrixFloat44 p_matrix
Projection matrix, computed by renderNormalScene() from all the parameters above. ...
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:225
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:33
void renderViewportBorder() const
Render the viewport border, if enabled.
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: exceptions.h:69
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.
mrpt::math::TPose3D getPose() const
Returns the 3D pose of the object as TPose3D.
bool is6DOFMode() const
Definition: CCamera.h:83
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.
T::Ptr getByClass(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...
double m_view_x
The viewport position [0,1].
Lighting parameters, mostly for triangle shaders.
mrpt::img::TColorf shadow_color
Definition: opengl_fonts.h:49
static Ptr Create(Args &&... args)
Definition: CSetOfLines.h:35
void setCurrentCameraFromPose(mrpt::poses::CPose3D &p)
Changes the point of view of the camera, from a given pose.
static constexpr shader_id_t POINTS
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:148
float vfont_scale
Size of characters [pixels].
Definition: opengl_fonts.h:44
bool is_projective
true: projective, false: ortho
std::map< shader_id_t, std::multimap< float, RenderQueueElement > > RenderQueue
A queue for rendering, sorted by shader program to minimize changes of OpenGL shader programs while r...
Definition: RenderQueue.h:46
bool m_isCloned
Set by setCloneView.
3D line, represented by a base point and a director vector.
Definition: TLine3D.h:19



Page generated by Doxygen 1.8.14 for MRPT 2.0.4 Git: 3e8ecd670 Mon May 18 14:23:19 2020 +0200 at lun may 18 14:30:11 CEST 2020