MRPT  2.0.4
CGlCanvasBase.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 "gui-precomp.h" // Precompiled headers
11 
12 #include <mrpt/gui/CGlCanvasBase.h>
13 #include <mrpt/opengl/opengl_api.h>
14 #include <mrpt/system/CTicTac.h>
15 #include <cstdlib>
16 
17 #if MRPT_HAS_OPENGL_GLUT
18 #ifdef _WIN32
19 // Windows:
20 #include <windows.h>
21 #endif
22 
23 #ifdef __APPLE__
24 #include <GLUT/glut.h>
25 #include <OpenGL/gl.h>
26 #include <OpenGL/glu.h>
27 #else
28 #include <GL/gl.h>
29 #include <GL/glu.h>
30 #include <GL/glut.h>
31 #ifdef HAVE_FREEGLUT_EXT_H
32 #include <GL/freeglut_ext.h>
33 #endif
34 #endif
35 #endif // MRPT_HAS_OPENGL_GLUT
36 
37 using namespace mrpt;
38 using namespace mrpt::gui;
39 using namespace mrpt::opengl;
40 using namespace std;
42 
44 
46 
48 {
49  // Ensure all OpenGL resources are freed before the opengl context is gone:
50  if (m_openGLScene) m_openGLScene->unloadShaders();
51 }
52 
53 void CGlCanvasBase::setMinimumZoom(float zoom) { m_minZoom = zoom; }
54 void CGlCanvasBase::setMaximumZoom(float zoom) { m_maxZoom = zoom; }
55 void CGlCanvasBase::setMousePos(int x, int y)
56 {
57  m_mouseClickX = x;
58  m_mouseClickY = y;
59 }
60 
61 void CGlCanvasBase::setMouseClicked(bool is) { mouseClicked = is; }
62 void CGlCanvasBase::updateZoom(CamaraParams& params, int x, int y) const
63 {
64  float zoom = params.cameraZoomDistance * exp(0.01f * (y - m_mouseClickY));
65  if (zoom <= m_minZoom || (m_maxZoom != -1.0f && m_maxZoom <= zoom)) return;
66  params.cameraZoomDistance = zoom;
67  if (params.cameraZoomDistance < 0.01f) params.cameraZoomDistance = 0.01f;
68 
69  float Az = -0.05f * (x - m_mouseClickX);
70  float D = 0.001f * params.cameraZoomDistance;
71  params.cameraPointingZ += D * Az;
72 }
73 
75 {
76  float zoom = params.cameraZoomDistance * (1 - 0.03f * (delta / 120.0f));
77  if (zoom <= m_minZoom || (m_maxZoom != -1.0f && m_maxZoom <= zoom)) return;
78 
79  params.cameraZoomDistance = zoom;
80 }
81 
82 // Required, for example, when missing "button down" events happen if
83 // the mouse clicks on a nanogui component, *then* moves out of it
84 // while still pressing a button:
85 inline void mouseGlitchFilter(
86  const int x, const int y, const int& mouseClickX, const int& mouseClickY)
87 {
88  if (std::abs(x - mouseClickX) > 60) const_cast<int&>(mouseClickX) = x;
89  if (std::abs(y - mouseClickY) > 60) const_cast<int&>(mouseClickY) = y;
90 }
91 
93 {
94  mouseGlitchFilter(x, y, m_mouseClickX, m_mouseClickY);
95 
96  const float dis = max(0.01f, (params.cameraZoomDistance));
97  float eye_x =
98  params.cameraPointingX + dis * cos(DEG2RAD(params.cameraAzimuthDeg)) *
99  cos(DEG2RAD(params.cameraElevationDeg));
100  float eye_y =
101  params.cameraPointingY + dis * sin(DEG2RAD(params.cameraAzimuthDeg)) *
102  cos(DEG2RAD(params.cameraElevationDeg));
103  float eye_z =
104  params.cameraPointingZ + dis * sin(DEG2RAD(params.cameraElevationDeg));
105 
106  // Orbit camera:
107  float A_AzimuthDeg = -SENSIBILITY_DEG_PER_PIXEL * (x - m_mouseClickX);
108  params.cameraAzimuthDeg += A_AzimuthDeg;
109 
110  float A_ElevationDeg = SENSIBILITY_DEG_PER_PIXEL * (y - m_mouseClickY);
111  params.setElevationDeg(params.cameraElevationDeg + A_ElevationDeg);
112 
113  // Move cameraPointing pos:
114  params.cameraPointingX =
115  eye_x - dis * cos(DEG2RAD(params.cameraAzimuthDeg)) *
116  cos(DEG2RAD(params.cameraElevationDeg));
117  params.cameraPointingY =
118  eye_y - dis * sin(DEG2RAD(params.cameraAzimuthDeg)) *
119  cos(DEG2RAD(params.cameraElevationDeg));
120  params.cameraPointingZ =
121  eye_z - dis * sin(DEG2RAD(params.cameraElevationDeg));
122 }
123 
125 {
126  mouseGlitchFilter(x, y, m_mouseClickX, m_mouseClickY);
127 
128  params.cameraAzimuthDeg -= 0.2f * (x - m_mouseClickX);
129  params.setElevationDeg(
130  params.cameraElevationDeg + 0.2f * (y - m_mouseClickY));
131 }
132 
134 {
135  m_mouseLastX = x;
136  m_mouseLastY = y;
137 }
138 
140 {
141 #if MRPT_HAS_OPENGL_GLUT
142  if (w == -1 || h == -1) return;
143 
144  glViewport(0, 0, (GLint)w, (GLint)h);
145 #endif
146 }
147 
149 {
150 #if MRPT_HAS_OPENGL_GLUT
151  glClearColor(clearColorR, clearColorG, clearColorB, clearColorA);
152 #endif
153 }
154 
155 void CGlCanvasBase::updatePan(CamaraParams& params, int x, int y) const
156 {
157  float Ay = -(x - m_mouseClickX);
158  float Ax = -(y - m_mouseClickY);
159  float D = 0.001f * params.cameraZoomDistance;
160  params.cameraPointingX += D * (Ax * cos(DEG2RAD(params.cameraAzimuthDeg)) -
161  Ay * sin(DEG2RAD(params.cameraAzimuthDeg)));
162  params.cameraPointingY += D * (Ax * sin(DEG2RAD(params.cameraAzimuthDeg)) +
163  Ay * cos(DEG2RAD(params.cameraAzimuthDeg)));
164 }
165 
167 {
168  return m_cameraParams;
169 }
170 
172 {
173  return m_cameraParams;
174 }
175 
177 {
178  m_cameraParams = params;
179 }
180 
182 {
183  return m_cameraParams.cameraZoomDistance;
184 }
185 
187 {
188  m_cameraParams.cameraZoomDistance = zoom;
189 }
190 
192 {
193  cam.setPointingAt(
194  m_cameraParams.cameraPointingX, m_cameraParams.cameraPointingY,
195  m_cameraParams.cameraPointingZ);
196  cam.setZoomDistance(m_cameraParams.cameraZoomDistance);
197  cam.setAzimuthDegrees(m_cameraParams.cameraAzimuthDeg);
198  cam.setElevationDegrees(m_cameraParams.cameraElevationDeg);
199  cam.setProjectiveModel(m_cameraParams.cameraIsProjective);
200  cam.setProjectiveFOVdeg(m_cameraParams.cameraFOV);
201 
202  return cam;
203 }
204 
205 void CGlCanvasBase::setUseCameraFromScene(bool is) { useCameraFromScene = is; }
206 bool CGlCanvasBase::getUseCameraFromScene() const { return useCameraFromScene; }
208 {
209  m_cameraParams.cameraAzimuthDeg = ang;
210 }
211 
213 {
214  m_cameraParams.cameraElevationDeg = ang;
215 }
216 
218 {
219  return m_cameraParams.cameraAzimuthDeg;
220 }
221 
223 {
224  return m_cameraParams.cameraElevationDeg;
225 }
226 
228 {
229  m_cameraParams.cameraIsProjective = is;
230 }
231 
233 {
234  return m_cameraParams.cameraIsProjective;
235 }
236 
237 void CGlCanvasBase::setCameraFOV(float FOV) { m_cameraParams.cameraFOV = FOV; }
238 float CGlCanvasBase::cameraFOV() const { return m_cameraParams.cameraFOV; }
239 void CGlCanvasBase::setClearColors(float r, float g, float b, float a)
240 {
241  clearColorR = r;
242  clearColorG = g;
243  clearColorB = b;
244  clearColorA = a;
245 }
246 
247 float CGlCanvasBase::getClearColorR() const { return clearColorR; }
248 float CGlCanvasBase::getClearColorG() const { return clearColorG; }
249 float CGlCanvasBase::getClearColorB() const { return clearColorB; }
250 float CGlCanvasBase::getClearColorA() const { return clearColorA; }
252 {
253  m_openGLScene = scene;
254 }
255 
256 void CGlCanvasBase::setCameraPointing(float pointX, float pointY, float pointZ)
257 {
258  m_cameraParams.cameraPointingX = pointX;
259  m_cameraParams.cameraPointingY = pointY;
260  m_cameraParams.cameraPointingZ = pointZ;
261 }
262 
264 {
265  return m_cameraParams.cameraPointingX;
266 }
267 
269 {
270  return m_cameraParams.cameraPointingY;
271 }
272 
274 {
275  return m_cameraParams.cameraPointingZ;
276 }
277 
278 double CGlCanvasBase::renderCanvas(int width, int height)
279 {
280 #if MRPT_HAS_OPENGL_GLUT
281  CTicTac tictac;
282  double At = 0.1;
283 
284  try
285  {
286  // Call PreRender user code:
287  preRender();
288  CHECK_OPENGL_ERROR();
289 
290  // Set static configs:
291  glEnable(GL_DEPTH_TEST);
292  CHECK_OPENGL_ERROR();
293 
294  // Set the viewport
295  resizeViewport((GLsizei)width, (GLsizei)height);
296 
297  // Set the background color:
298  clearColors();
299 
300  if (m_openGLScene)
301  {
302  // Set the camera params in the scene:
303  if (!useCameraFromScene)
304  {
305  COpenGLViewport::Ptr view = m_openGLScene->getViewport("main");
306  if (!view)
307  {
309  "Fatal error: there is no 'main' viewport in the 3D "
310  "scene!");
311  }
312 
313  mrpt::opengl::CCamera& cam = view->getCamera();
314  updateCameraParams(cam);
315  }
316 
317  tictac.Tic();
318 
319  // Draw primitives:
320  m_openGLScene->render();
321 
322  } // end if "m_openGLScene!=nullptr"
323 
324  postRender();
325 
326  // Flush & swap buffers to disply new image:
327  glFinish();
328  swapBuffers();
329  CHECK_OPENGL_ERROR();
330 
331  At = tictac.Tac();
332  }
333  catch (const std::exception& e)
334  {
335  const std::string err_msg =
336  std::string("[CGLCanvasBase::Render] Exception:\n") +
338  std::cerr << err_msg;
339  renderError(err_msg);
340  }
341 
342  return At;
343 #else
344  THROW_EXCEPTION("Cant render: MRPT was built without OpenGL");
345 #endif
346 }
347 
349 {
350  cameraElevationDeg = deg;
351 
352  if (cameraElevationDeg < -90.0f)
353  cameraElevationDeg = -90.0f;
354  else if (cameraElevationDeg > 90.0f)
355  cameraElevationDeg = 90.0f;
356 }
357 
358 void CGlCanvasBaseHeadless::renderError(const std::string& e)
359 {
360  std::cerr << "[CGlCanvasBaseHeadless::renderError] Error:" << e
361  << std::endl;
362 }
float getCameraPointingX() const
Returns the x pointing of the camera See also setCameraPointing(float, float, float) ...
double Tac() noexcept
Stops the stopwatch.
Definition: CTicTac.cpp:87
virtual void setCameraProjective(bool is)
void updateOrbitCamera(CamaraParams &params, int x, int y) const
This function for the mouse event It gets a reference to CamaraParams, x, y and updates the elevation...
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
CamaraParams cameraParams() const
Returns a copy of CamaraParams See also getRefCameraParams(), setCameraParams(const CamaraParams &) ...
A high-performance stopwatch, with typical resolution of nanoseconds.
void setProjectiveModel(bool v=true)
Enable/Disable projective mode (vs.
Definition: CCamera.h:70
void setMaximumZoom(float zoom)
Sets the maximum of the zoom See also setMinimumZoom(float)
float getZoomDistance() const
Returns a zoom See also setZoomDistance(float)
mrpt::vision::TStereoCalibParams params
STL namespace.
virtual void setCameraParams(const CamaraParams &params)
Sets the CamaraParams See also cameraParams(), getRefCameraParams()
void resizeViewport(int w, int h)
Calls the glViewport function.
const CamaraParams & getRefCameraParams() const
Returns a reference to CamaraParams See also cameraParams(), setCameraParams(const CamaraParams &) ...
void setMousePos(int x, int y)
Saves the click position of the mouse See also setMouseClicked(bool)
virtual void setElevationDegrees(float ang)
Saves the degrees of the elevation camera See also getElevationDegrees()
void setZoomDistance(float z)
Definition: CCamera.h:63
mrpt::system::CTicTac CTicTac
Definition: utils/CTicTac.h:5
void setAzimuthDegrees(float ang)
Definition: CCamera.h:67
virtual void renderError(const std::string &e) override
void setOpenGLSceneRef(mrpt::opengl::COpenGLScene::Ptr scene)
virtual void setAzimuthDegrees(float ang)
Saves the degrees of the azimuth camera See also getAzimuthDegrees()
virtual double renderCanvas(int width=-1, int height=-1)
constexpr double DEG2RAD(const double x)
Degrees to radians.
virtual void setCameraPointing(float pointX, float pointY, float pointZ)
Saves the pointing of the camera See also getCameraPointingX(), getCameraPointingY(), getCameraPointingZ()
void clearColors()
Calls the glClearColor function See also setClearColors(float, float, float, float) ...
void setProjectiveFOVdeg(float ang)
Vertical field-of-View in degs, only when projectiveModel=true (default=30 deg).
Definition: CCamera.h:87
float getCameraPointingZ() const
Returns the z pointing of the camera See also setCameraPointing(float, float, float) ...
virtual void setCameraFOV(float FOV)
void setClearColors(float r, float g, float b, float a=1.0f)
Sets the RGBA colors for glClearColor See also clearColors(), getClearColorR(), getClearColorG(),getClearColorB(), getClearColorA()
virtual void setZoomDistance(float zoom)
Saves camera zooming See also getZoomDistance()
bool getUseCameraFromScene() const
See also void setUseCameraFromScene(bool)
float getAzimuthDegrees() const
Returns a azimuth degrees See also setAzimuthDegrees(float)
float getCameraPointingY() const
Returns the y pointing of the camera See also setCameraPointing(float, float, float) ...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void setElevationDegrees(float ang)
Definition: CCamera.h:68
void setMouseClicked(bool is)
Sets the property mouseClicked By default, this property is false.
void mouseGlitchFilter(const int x, const int y, const int &mouseClickX, const int &mouseClickY)
void updateLastPos(int x, int y)
Sets the last mouse position.
float getElevationDegrees() const
Returns a elevation degrees See also setElevationDegrees(float)
void updateRotate(CamaraParams &params, int x, int y) const
This function for the mouse event It gets a reference to CamaraParams, x, y and updates the elevation...
void setMinimumZoom(float zoom)
Sets the minimum of the zoom See also setMaximumZoom(float)
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
std::string exception_to_str(const std::exception &e)
Builds a nice textual representation of a nested exception, which if generated using MRPT macros (THR...
Definition: exceptions.cpp:59
void setUseCameraFromScene(bool is)
If set to true (default=false), the cameraPointingX,...
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
void Tic() noexcept
Starts the stopwatch.
Definition: CTicTac.cpp:76
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:33
static float SENSIBILITY_DEG_PER_PIXEL
void updatePan(CamaraParams &params, int x, int y) const
This function for the mouse event It gets a reference to CamaraParams, x, y and updates the pointing ...
mrpt::opengl::CCamera & updateCameraParams(mrpt::opengl::CCamera &cam) const
This function gets a reference to mrpt::opengl::CCamera and updates the camera parameters(pointing, zoom, azimuth, elevation, IsProjective, FOV)
void updateZoom(CamaraParams &params, int x, int y) const
This function for the mouse event It gets a reference to CamaraParams, x, y and updates the zoom of t...
void setPointingAt(float x, float y, float z)
Definition: CCamera.h:41



Page generated by Doxygen 1.8.14 for MRPT 2.0.4 Git: 33de1d0ad Sat Jun 20 11:02:42 2020 +0200 at sáb jun 20 17:35:17 CEST 2020