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 }
mrpt::gui::CGlCanvasBase::getRefCameraParams
const CamaraParams & getRefCameraParams() const
Returns a reference to CamaraParams See also cameraParams(), setCameraParams(const CamaraParams &)
Definition: CGlCanvasBase.cpp:171
opengl_api.h
mrpt::gui::CGlCanvasBase::updateOrbitCamera
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...
Definition: CGlCanvasBase.cpp:124
mrpt::gui::CGlCanvasBase::updateZoom
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...
Definition: CGlCanvasBase.cpp:62
mrpt::gui::CGlCanvasBase::updateCameraParams
mrpt::opengl::CCamera & updateCameraParams(mrpt::opengl::CCamera &cam) const
This function gets a reference to mrpt::opengl::CCamera and updates the camera parameters(pointing,...
Definition: CGlCanvasBase.cpp:191
mrpt::opengl::CCamera::setAzimuthDegrees
void setAzimuthDegrees(float ang)
Definition: CCamera.h:67
mrpt::gui::CGlCanvasBase::getUseCameraFromScene
bool getUseCameraFromScene() const
See also void setUseCameraFromScene(bool)
Definition: CGlCanvasBase.cpp:206
mrpt::gui::CGlCanvasBase::getCameraPointingZ
float getCameraPointingZ() const
Returns the z pointing of the camera See also setCameraPointing(float, float, float)
Definition: CGlCanvasBase.cpp:273
mrpt::gui::CGlCanvasBase::getAzimuthDegrees
float getAzimuthDegrees() const
Returns a azimuth degrees See also setAzimuthDegrees(float)
Definition: CGlCanvasBase.cpp:217
mrpt::gui::CGlCanvasBase::setCameraProjective
virtual void setCameraProjective(bool is)
Definition: CGlCanvasBase.cpp:227
mrpt::gui::CGlCanvasBase::SENSIBILITY_DEG_PER_PIXEL
static float SENSIBILITY_DEG_PER_PIXEL
Definition: CGlCanvasBase.h:187
mrpt::gui::CGlCanvasBase::getClearColorG
float getClearColorG() const
Definition: CGlCanvasBase.cpp:248
mrpt::opengl::CCamera::setProjectiveModel
void setProjectiveModel(bool v=true)
Enable/Disable projective mode (vs.
Definition: CCamera.h:70
mrpt::system::CTicTac
A high-performance stopwatch, with typical resolution of nanoseconds.
Definition: system/CTicTac.h:17
mrpt::opengl::CCamera::setProjectiveFOVdeg
void setProjectiveFOVdeg(float ang)
Vertical field-of-View in degs, only when projectiveModel=true (default=30 deg).
Definition: CCamera.h:87
mrpt::gui::CGlCanvasBase::updateRotate
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...
Definition: CGlCanvasBase.cpp:92
mrpt::gui::CGlCanvasBase::updatePan
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 ...
Definition: CGlCanvasBase.cpp:155
mrpt::gui::CGlCanvasBase::setMaximumZoom
void setMaximumZoom(float zoom)
Sets the maximum of the zoom See also setMinimumZoom(float)
Definition: CGlCanvasBase.cpp:54
mrpt::gui::CGlCanvasBase::CamaraParams::setElevationDeg
void setElevationDeg(float deg)
Definition: CGlCanvasBase.cpp:348
mrpt::gui::CGlCanvasBase::setCameraParams
virtual void setCameraParams(const CamaraParams &params)
Sets the CamaraParams See also cameraParams(), getRefCameraParams()
Definition: CGlCanvasBase.cpp:176
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: BaseAppDataSource.h:15
mrpt::gui::CGlCanvasBase::setClearColors
void setClearColors(float r, float g, float b, float a=1.0f)
Sets the RGBA colors for glClearColor See also clearColors(), getClearColorR(), getClearColorG(),...
Definition: CGlCanvasBase.cpp:239
CGlCanvasBase.h
mrpt::opengl::CCamera::setPointingAt
void setPointingAt(float x, float y, float z)
Definition: CCamera.h:41
THROW_EXCEPTION
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
mrpt::gui::CGlCanvasBase::isCameraProjective
bool isCameraProjective() const
Definition: CGlCanvasBase.cpp:232
mrpt::gui::CGlCanvasBase::setAzimuthDegrees
virtual void setAzimuthDegrees(float ang)
Saves the degrees of the azimuth camera See also getAzimuthDegrees()
Definition: CGlCanvasBase.cpp:207
mrpt::system::CTicTac::Tac
double Tac() noexcept
Stops the stopwatch.
Definition: CTicTac.cpp:87
mrpt::gui::CGlCanvasBase::getCameraPointingY
float getCameraPointingY() const
Returns the y pointing of the camera See also setCameraPointing(float, float, float)
Definition: CGlCanvasBase.cpp:268
mrpt::opengl::COpenGLViewport::Ptr
std::shared_ptr< mrpt::opengl ::COpenGLViewport > Ptr
Definition: COpenGLViewport.h:65
mrpt::utils::CTicTac
mrpt::system::CTicTac CTicTac
Definition: utils/CTicTac.h:5
mouseGlitchFilter
void mouseGlitchFilter(const int x, const int y, const int &mouseClickX, const int &mouseClickY)
Definition: CGlCanvasBase.cpp:85
mrpt::gui::CGlCanvasBase::updateLastPos
void updateLastPos(int x, int y)
Sets the last mouse position.
Definition: CGlCanvasBase.cpp:133
mrpt::opengl::CCamera
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:33
mrpt::gui::CGlCanvasBase::getZoomDistance
float getZoomDistance() const
Returns a zoom See also setZoomDistance(float)
Definition: CGlCanvasBase.cpp:181
gui-precomp.h
mrpt::gui::CGlCanvasBase::~CGlCanvasBase
virtual ~CGlCanvasBase()
Definition: CGlCanvasBase.cpp:47
mrpt::opengl::CCamera::setZoomDistance
void setZoomDistance(float z)
Definition: CCamera.h:63
mrpt::system::CTicTac::Tic
void Tic() noexcept
Starts the stopwatch.
Definition: CTicTac.cpp:76
mrpt::gui::CGlCanvasBase::clearColors
void clearColors()
Calls the glClearColor function See also setClearColors(float, float, float, float)
Definition: CGlCanvasBase.cpp:148
mrpt::gui::CGlCanvasBase::cameraFOV
float cameraFOV() const
Definition: CGlCanvasBase.cpp:238
mrpt::gui::CGlCanvasBase::getClearColorA
float getClearColorA() const
Definition: CGlCanvasBase.cpp:250
mrpt::DEG2RAD
constexpr double DEG2RAD(const double x)
Degrees to radians
Definition: core/include/mrpt/core/bits_math.h:47
params
mrpt::vision::TStereoCalibParams params
Definition: chessboard_stereo_camera_calib_unittest.cpp:24
mrpt::gui
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
mrpt::gui::CGlCanvasBase::getElevationDegrees
float getElevationDegrees() const
Returns a elevation degrees See also setElevationDegrees(float)
Definition: CGlCanvasBase.cpp:222
mrpt::opengl::COpenGLScene::Ptr
std::shared_ptr< mrpt::opengl ::COpenGLScene > Ptr
Definition: COpenGLScene.h:58
mrpt::gui::CGlCanvasBase::CGlCanvasBase
CGlCanvasBase()
Definition: CGlCanvasBase.cpp:45
mrpt::gui::CGlCanvasBase::CamaraParams
Definition: CGlCanvasBase.h:27
mrpt::gui::CGlCanvasBase::setOpenGLSceneRef
void setOpenGLSceneRef(mrpt::opengl::COpenGLScene::Ptr scene)
Definition: CGlCanvasBase.cpp:251
CTicTac.h
mrpt::opengl::CCamera::setElevationDegrees
void setElevationDegrees(float ang)
Definition: CCamera.h:68
mrpt::gui::CGlCanvasBase::setCameraFOV
virtual void setCameraFOV(float FOV)
Definition: CGlCanvasBase.cpp:237
mrpt::gui::CGlCanvasBase::getClearColorB
float getClearColorB() const
Definition: CGlCanvasBase.cpp:249
mrpt::gui::CGlCanvasBase::renderCanvas
virtual double renderCanvas(int width=-1, int height=-1)
Definition: CGlCanvasBase.cpp:278
mrpt::gui::CGlCanvasBase::getCameraPointingX
float getCameraPointingX() const
Returns the x pointing of the camera See also setCameraPointing(float, float, float)
Definition: CGlCanvasBase.cpp:263
mrpt::gui::CGlCanvasBaseHeadless::renderError
virtual void renderError(const std::string &e) override
Definition: CGlCanvasBase.cpp:358
mrpt::gui::CGlCanvasBase::setCameraPointing
virtual void setCameraPointing(float pointX, float pointY, float pointZ)
Saves the pointing of the camera See also getCameraPointingX(), getCameraPointingY(),...
Definition: CGlCanvasBase.cpp:256
mrpt::gui::CGlCanvasBase::resizeViewport
void resizeViewport(int w, int h)
Calls the glViewport function.
Definition: CGlCanvasBase.cpp:139
mrpt::exception_to_str
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
mrpt::gui::CGlCanvasBase::setMousePos
void setMousePos(int x, int y)
Saves the click position of the mouse See also setMouseClicked(bool)
Definition: CGlCanvasBase.cpp:55
mrpt::gui::CGlCanvasBase::setElevationDegrees
virtual void setElevationDegrees(float ang)
Saves the degrees of the elevation camera See also getElevationDegrees()
Definition: CGlCanvasBase.cpp:212
mrpt::opengl
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
mrpt::gui::CGlCanvasBase::setMouseClicked
void setMouseClicked(bool is)
Sets the property mouseClicked By default, this property is false.
Definition: CGlCanvasBase.cpp:61
mrpt::gui::CGlCanvasBase::getClearColorR
float getClearColorR() const
Definition: CGlCanvasBase.cpp:247
mrpt::gui::CGlCanvasBase::setMinimumZoom
void setMinimumZoom(float zoom)
Sets the minimum of the zoom See also setMaximumZoom(float)
Definition: CGlCanvasBase.cpp:53
mrpt::gui::CGlCanvasBase::setUseCameraFromScene
void setUseCameraFromScene(bool is)
If set to true (default=false), the cameraPointingX,...
Definition: CGlCanvasBase.cpp:205
mrpt::gui::CGlCanvasBase::cameraParams
CamaraParams cameraParams() const
Returns a copy of CamaraParams See also getRefCameraParams(), setCameraParams(const CamaraParams &)
Definition: CGlCanvasBase.cpp:166
mrpt::gui::CGlCanvasBase::setZoomDistance
virtual void setZoomDistance(float zoom)
Saves camera zooming See also getZoomDistance()
Definition: CGlCanvasBase.cpp:186



Page generated by Doxygen 1.8.17 for MRPT 2.0.4 at Fri Jul 17 08:43:33 UTC 2020