qtopengl_widget.cpp
Go to the documentation of this file.
1 
7 #include "qtopengl_widget.h"
8 #include "qtopengl_main_window.h"
10 
11 #include <argos3/core/utility/logging/argos_log.h>
12 #include <argos3/core/utility/math/plane.h>
13 #include <argos3/core/simulator/simulator.h>
14 #include <argos3/core/simulator/loop_functions.h>
15 #include <argos3/core/simulator/space/space.h>
16 #include <argos3/core/simulator/entity/floor_entity.h>
17 #include <argos3/core/simulator/entity/composable_entity.h>
18 #include <argos3/core/simulator/entity/positional_entity.h>
19 
20 #include <QDir>
21 #include <QToolTip>
22 #include <QTimerEvent>
23 #include <QMouseEvent>
24 #include <QWheelEvent>
25 #include <QPainter>
26 #include <QOpenGLFramebufferObject>
27 
28 #ifndef GL_MULTISAMPLE
29 #define GL_MULTISAMPLE 0x809D
30 #endif
31 
32 namespace argos {
33 
34  static const Real ASPECT_RATIO = 4.0f / 3.0f;
35 
36  /****************************************/
37  /****************************************/
38 
40  CQTOpenGLMainWindow& c_main_window,
41  CQTOpenGLUserFunctions& c_user_functions) :
42  QOpenGLWidget(pc_parent),
43  m_cMainWindow(c_main_window),
44  m_cUserFunctions(c_user_functions),
45  nTimerId(-1),
46  m_bFastForwarding(false),
47  m_nDrawFrameEvery(1),
48  m_nFrameCounter(0),
49  m_bMouseGrabbed(false),
50  m_bShiftPressed(false),
51  m_bInvertMouse(false),
52  m_cSimulator(CSimulator::GetInstance()),
53  m_cSpace(m_cSimulator.GetSpace()),
54  m_bShowBoundary(true),
55  m_bUsingFloorTexture(false),
56  m_pcFloorTexture(nullptr),
57  m_pcGroundTexture(nullptr) {
58  /* Set the widget's size policy */
59  QSizePolicy cSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
60  cSizePolicy.setHeightForWidth(true);
61  setSizePolicy(cSizePolicy);
62  /* Grab focus when clicked on */
63  setFocusPolicy(Qt::ClickFocus);
64  /* Force size and geometry */
65  updateGeometry();
66  /* Keys */
67  m_mapPressedKeys[DIRECTION_UP] = false;
68  m_mapPressedKeys[DIRECTION_DOWN] = false;
69  m_mapPressedKeys[DIRECTION_LEFT] = false;
70  m_mapPressedKeys[DIRECTION_RIGHT] = false;
71  m_mapPressedKeys[DIRECTION_FORWARDS] = false;
72  m_mapPressedKeys[DIRECTION_BACKWARDS] = false;
73  }
74 
75  /****************************************/
76  /****************************************/
77 
79  makeCurrent();
80  delete m_pcGroundTexture;
81  if(m_bUsingFloorTexture) {
82  delete m_pcFloorTexture;
83  }
84  doneCurrent();
85  }
86 
87  /****************************************/
88  /****************************************/
89 
91  /* Initializes the openGL functions */
92  initializeOpenGLFunctions();
93  /* Set clear color */
94  glClearColor(0, .5, .5, 255); // dark cyan
95  /* Set up the texture parameters for the floor plane
96  (here we refer to the standard floor, not the floor entity) */
97  m_pcGroundTexture = new QOpenGLTexture(QImage(m_cMainWindow.GetTextureDir() + "/ground.png"));
98  m_pcGroundTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,
99  QOpenGLTexture::Linear);
100 #ifdef ARGOS_WITH_FREEIMAGE
101  /* Now take care of the floor entity */
102  try {
103  /* Create an image to use as texture */
104  m_cSpace.GetFloorEntity().SaveAsImage("/tmp/argos_floor.png");
105  m_bUsingFloorTexture = true;
106  /* Use the image as texture */
107  m_pcFloorTexture = new QOpenGLTexture(QImage("/tmp/argos_floor.png"));
108  m_pcFloorTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,
109  QOpenGLTexture::Linear);
110  m_cSpace.GetFloorEntity().ClearChanged();
111  }
112  catch(CARGoSException& ex) {}
113 #endif
114  /* Nicest hints */
115  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
116  glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
117  /* Setup lighting */
118  GLfloat pfLightAmbient[] = { .2f, .2f, .2f, 1.0f };
119  GLfloat pfLightDiffuse[] = { .8f, .8f, .8f, 1.0f };
120  GLfloat pfLightPosition[] = { 50.0f , 50.0f , 2.0f , 1.0f };
121  glLightfv(GL_LIGHT0, GL_AMBIENT, pfLightAmbient);
122  glLightfv(GL_LIGHT0, GL_DIFFUSE, pfLightDiffuse);
123  glLightfv(GL_LIGHT0, GL_POSITION, pfLightPosition);
124  glEnable(GL_LIGHT0);
125  }
126 
127  /****************************************/
128  /****************************************/
129 
131  /* Clear accumulator buffer */
132  glClearAccum(0.0, 0.0, 0.0, 0.0);
133  /* Clear color buffer and depth buffer */
134  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
135  /* Smooth lines and shades */
136  glEnable(GL_LINE_SMOOTH);
137  glShadeModel(GL_SMOOTH);
138  /* Enable depth testing */
139  glEnable(GL_DEPTH_TEST);
140  /* Enable face culling */
141  glEnable(GL_CULL_FACE);
142  /* Enable lighting */
143  glEnable(GL_LIGHTING);
144  /* Calculate the perspective matrix */
145  glMatrixMode(GL_PROJECTION);
146  glLoadIdentity();
147  gluPerspective(m_cCamera.GetActivePlacement().YFieldOfView.GetValue(),
148  ASPECT_RATIO,
149  0.1f, 1000.0f);
150  /* Place the camera */
151  glMatrixMode(GL_MODELVIEW);
152  glLoadIdentity();
153  m_cCamera.Look();
154  /* Draw the arena */
155  DrawArena();
156  /* Draw the objects */
157  CEntity::TVector& vecEntities = m_cSpace.GetRootEntityVector();
158  for(auto itEntities = vecEntities.begin();
159  itEntities != vecEntities.end();
160  ++itEntities) {
161  glPushMatrix();
162  CallEntityOperation<CQTOpenGLOperationDrawNormal, CQTOpenGLWidget, void>(*this, **itEntities);
163  m_cUserFunctions.Call(**itEntities);
164  glPopMatrix();
165  }
166  /* Draw the selected object, if necessary */
167  if(m_sSelectionInfo.IsSelected) {
168  glPushMatrix();
169  CallEntityOperation<CQTOpenGLOperationDrawSelected, CQTOpenGLWidget, void>(*this, *m_sSelectionInfo.Entity);
170  glPopMatrix();
171  }
172  /* Draw in world */
173  glPushMatrix();
174  m_cUserFunctions.DrawInWorld();
175  glPopMatrix();
176  /* Draw axes */
177  DrawAxes();
178  /* Execute overlay drawing */
179  glShadeModel(GL_FLAT);
180  glDisable(GL_LIGHTING);
181  glDisable(GL_CULL_FACE);
182  glDisable(GL_DEPTH_TEST);
183  glMatrixMode(GL_MODELVIEW);
184  QPainter cPainter(this);
185  cPainter.setRenderHint(QPainter::Antialiasing);
186  cPainter.setRenderHint(QPainter::TextAntialiasing);
187  m_cUserFunctions.DrawOverlay(cPainter);
188  // cPainter.drawText(rect(), QString("%1 FPS").arg(m_fFPS, 0, 'f', 0));
189  cPainter.end();
190  /* Grab frame, if necessary */
191  if(m_sFrameGrabData.GUIGrabbing || m_sFrameGrabData.HeadlessGrabbing) {
192  QString strFileName = QString("%1/%2%3.%4")
193  .arg(m_sFrameGrabData.Directory)
194  .arg(m_sFrameGrabData.BaseName)
195  .arg(m_cSpace.GetSimulationClock(), 10, 10, QChar('0'))
196  .arg(m_sFrameGrabData.Format);
197  QToolTip::showText(pos() + geometry().center(), "Stored frame to \"" + strFileName);
198  grabFramebuffer()
199  .save(
200  strFileName,
201  nullptr,
202  m_sFrameGrabData.Quality);
203  }
204  }
205 
206  /****************************************/
207  /****************************************/
208 
210  int n_y) {
211  /* Make sure OpenGL context is correct */
212  makeCurrent();
213  /* Rescale coordinates by devicePixelRatio */
214  n_x *= devicePixelRatio();
215  n_y *= devicePixelRatio();
216  /* Get current viewport */
217  GLint nViewport[4];
218  glGetIntegerv(GL_VIEWPORT, nViewport);
219  /* Get OpenGL matrices */
220  GLdouble fModelViewMatrix[16];
221  GLdouble fProjectionMatrix[16];
222  glGetDoublev(GL_MODELVIEW_MATRIX, fModelViewMatrix);
223  glGetDoublev(GL_PROJECTION_MATRIX, fProjectionMatrix);
224  /*
225  * Convert mouse position in window into OpenGL representation
226  */
227  /* The x coordinate stays the same */
228  GLfloat fWinX = n_x;
229  /* The y coordinate of the window is top-left; in OpenGL is bottom-left */
230  GLfloat fWinY = nViewport[3] - n_y;
231  /*
232  * Get the position of the ray start in the world
233  * The ray starts at the near clipping plane (depth = 0.0f)
234  */
235  GLdouble fRayStartX, fRayStartY, fRayStartZ;
236  gluUnProject(fWinX, fWinY, 0.0f,
237  fModelViewMatrix, fProjectionMatrix, nViewport,
238  &fRayStartX, &fRayStartY, &fRayStartZ);
239  /*
240  * Get the position of the ray end in the world
241  * The ray starts at the far clipping plane (depth = 1.0f)
242  */
243  GLdouble fRayEndX, fRayEndY, fRayEndZ;
244  gluUnProject(fWinX, fWinY, 1.0f,
245  fModelViewMatrix, fProjectionMatrix, nViewport,
246  &fRayEndX, &fRayEndY, &fRayEndZ);
247  doneCurrent();
248  return CRay3(CVector3(fRayStartX, fRayStartY, fRayStartZ),
249  CVector3(fRayEndX, fRayEndY, fRayEndZ));
250  }
251 
252  /****************************************/
253  /****************************************/
254 
256  int n_y) {
257  /* Make sure OpenGL context is correct */
258  makeCurrent();
259  /* Rescale coordinates by devicePixelRatio */
260  n_x *= devicePixelRatio();
261  n_y *= devicePixelRatio();
262  /* Get current viewport */
263  GLint nViewport[4];
264  glGetIntegerv(GL_VIEWPORT, nViewport);
265  /* Get OpenGL matrices */
266  GLdouble fModelViewMatrix[16];
267  GLdouble fProjectionMatrix[16];
268  glGetDoublev(GL_MODELVIEW_MATRIX, fModelViewMatrix);
269  glGetDoublev(GL_PROJECTION_MATRIX, fProjectionMatrix);
270  /*
271  * Convert mouse position in window into a 3D representation
272  */
273  /* The x coordinate stays the same */
274  GLfloat fWinX = n_x;
275  /* The y coordinate of the window is top-left; in OpenGL is bottom-left */
276  GLfloat fWinY = nViewport[3] - n_y;
277  /* Read the z coordinate from the depth buffer in the back buffer */
278  GLfloat fWinZ;
279  glReadBuffer(GL_BACK);
280  glReadPixels(n_x, (GLint)fWinY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fWinZ);
281  /* Get the actual position in the world */
282  GLdouble fWorldX, fWorldY, fWorldZ;
283  gluUnProject(fWinX, fWinY, fWinZ,
284  fModelViewMatrix, fProjectionMatrix, nViewport,
285  &fWorldX, &fWorldY, &fWorldZ);
286  /*
287  * Swap coordinates when creating the ray
288  * In ARGoS, the up vector is the Z-axis, while in OpenGL it is the Y-axis
289  */
290  doneCurrent();
291  return CVector3(fWorldX, fWorldZ, fWorldY);
292  }
293 
294  /****************************************/
295  /****************************************/
296 
298  return (m_sSelectionInfo.IsSelected ?
299  m_sSelectionInfo.Entity :
300  nullptr);
301  }
302 
303  /****************************************/
304  /****************************************/
305 
307  /* Check whether an entity had previously been selected */
308  if(m_sSelectionInfo.IsSelected) {
309  /* An entity had previously been selected */
310  /* Is that entity already selected? */
311  if(m_sSelectionInfo.Entity == &c_entity) return;
312  /* Deselect the previous one */
313  emit EntityDeselected(m_sSelectionInfo.Entity);
314  m_cUserFunctions.EntityDeselected(
315  *m_sSelectionInfo.Entity);
316  }
317  else {
318  /* No entity had previously been selected */
319  m_sSelectionInfo.IsSelected = true;
320  }
321  /* Select the new entity */
322  m_sSelectionInfo.Entity = &c_entity;
323  emit EntitySelected(&c_entity);
324  m_cUserFunctions.EntitySelected(c_entity);
325  update();
326  }
327 
328  /****************************************/
329  /****************************************/
330 
332  /* If no entity was selected, nothing to do */
333  if(!m_sSelectionInfo.IsSelected) return;
334  /* Deselect the entity */
335  emit EntityDeselected(m_sSelectionInfo.Entity);
336  m_cUserFunctions.EntityDeselected(
337  *m_sSelectionInfo.Entity);
338  m_sSelectionInfo.IsSelected = false;
339  update();
340  }
341 
342  /****************************************/
343  /****************************************/
344 
346  UInt32 un_y) {
347  CRay3 cRay = RayFromWindowCoord(un_x, un_y);
351  else
352  DeselectEntity();
353  }
354 
355  /****************************************/
356  /****************************************/
357 
359  /* Get the position of the entity */
360  const CVector3& cPosition = c_entity.GetPosition();
361  /* Get the orientation of the entity */
362  const CQuaternion& cOrientation = c_entity.GetOrientation();
363  CRadians cZAngle, cYAngle, cXAngle;
364  cOrientation.ToEulerAngles(cZAngle, cYAngle, cXAngle);
365  /* First, translate the entity */
366  glTranslated(cPosition.GetX(), cPosition.GetY(), cPosition.GetZ());
367  /* Second, rotate the entity */
368  glRotated(ToDegrees(cXAngle).GetValue(), 1.0f, 0.0f, 0.0f);
369  glRotated(ToDegrees(cYAngle).GetValue(), 0.0f, 1.0f, 0.0f);
370  glRotated(ToDegrees(cZAngle).GetValue(), 0.0f, 0.0f, 1.0f);
371  }
372 
373  /****************************************/
374  /****************************************/
375 
377  /* Get the position of the entity */
378  const CVector3& cPosition = c_entity.GetOriginAnchor().Position;
379  /* Get the orientation of the entity */
380  const CQuaternion& cOrientation = c_entity.GetOriginAnchor().Orientation;
381  CRadians cZAngle, cYAngle, cXAngle;
382  cOrientation.ToEulerAngles(cZAngle, cYAngle, cXAngle);
383  /* First, translate the entity */
384  glTranslated(cPosition.GetX(), cPosition.GetY(), cPosition.GetZ());
385  /* Second, rotate the entity */
386  glRotated(ToDegrees(cXAngle).GetValue(), 1.0f, 0.0f, 0.0f);
387  glRotated(ToDegrees(cYAngle).GetValue(), 0.0f, 1.0f, 0.0f);
388  glRotated(ToDegrees(cZAngle).GetValue(), 0.0f, 0.0f, 1.0f);
389  }
390 
391  /****************************************/
392  /****************************************/
393 
395  if(! c_entity.GetCheckedRays().empty()) {
396  glDisable(GL_LIGHTING);
397  glLineWidth(1.0f);
398  glBegin(GL_LINES);
399  for(UInt32 i = 0; i < c_entity.GetCheckedRays().size(); ++i) {
400  if(c_entity.GetCheckedRays()[i].first) {
401  glColor3f(1.0, 0.0, 1.0);
402  }
403  else {
404  glColor3f(0.0, 1.0, 1.0);
405  }
406  const CVector3& cStart = c_entity.GetCheckedRays()[i].second.GetStart();
407  const CVector3& cEnd = c_entity.GetCheckedRays()[i].second.GetEnd();
408  glVertex3d(cStart.GetX(), cStart.GetY(), cStart.GetZ());
409  glVertex3d(cEnd.GetX(), cEnd.GetY(), cEnd.GetZ());
410  }
411  glEnd();
412  glPointSize(5.0);
413  glColor3f(0.0, 0.0, 0.0);
414  glBegin(GL_POINTS);
415  for(UInt32 i = 0; i < c_entity.GetIntersectionPoints().size(); ++i) {
416  const CVector3& cPoint = c_entity.GetIntersectionPoints()[i];
417  glVertex3d(cPoint.GetX(), cPoint.GetY(), cPoint.GetZ());
418  }
419  glEnd();
420  glPointSize(1.0);
421  glEnable(GL_LIGHTING);
422  }
423  }
424 
425  /****************************************/
426  /****************************************/
427 
429  const SBoundingBox& sBBox = c_entity.GetBoundingBox();
430  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
431  glDisable(GL_LIGHTING);
432  glLineWidth(3.0f);
433  glColor3f(1.0f, 1.0f, 1.0f);
434  /* This part covers the top and bottom faces (parallel to XY) */
435  glBegin(GL_QUADS);
436  /* Bottom face */
437  glNormal3d(0.0f, 0.0f, -1.0f);
438  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MinCorner.GetZ());
439  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MinCorner.GetZ());
440  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MinCorner.GetZ());
441  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MinCorner.GetZ());
442  /* Top face */
443  glNormal3d(0.0f, 0.0f, 1.0f);
444  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MaxCorner.GetZ());
445  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MaxCorner.GetZ());
446  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MaxCorner.GetZ());
447  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MaxCorner.GetZ());
448  glEnd();
449  /* This part covers the faces (South, East, North, West) */
450  glBegin(GL_QUADS);
451  /* South face */
452  glNormal3d(-1.0f, 0.0f, 0.0f);
453  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MinCorner.GetZ());
454  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MaxCorner.GetZ());
455  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MaxCorner.GetZ());
456  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MinCorner.GetZ());
457  /* East face */
458  glNormal3d(0.0f, -1.0f, 0.0f);
459  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MinCorner.GetZ());
460  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MinCorner.GetZ());
461  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MaxCorner.GetZ());
462  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MaxCorner.GetZ());
463  /* North face */
464  glNormal3d(1.0f, 0.0f, 0.0f);
465  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MinCorner.GetZ());
466  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MinCorner.GetZ());
467  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MaxCorner.GetZ());
468  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MinCorner.GetY(), sBBox.MaxCorner.GetZ());
469  /* West face */
470  glNormal3d(0.0f, 1.0f, 0.0f);
471  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MinCorner.GetZ());
472  glVertex3d(sBBox.MinCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MaxCorner.GetZ());
473  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MaxCorner.GetZ());
474  glVertex3d(sBBox.MaxCorner.GetX(), sBBox.MaxCorner.GetY(), sBBox.MinCorner.GetZ());
475  glEnd();
476  glEnable(GL_LIGHTING);
477  glLineWidth(1.0f);
478  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
479  }
480 
481  /****************************************/
482  /****************************************/
483 
485  m_bFastForwarding = false;
486  if(nTimerId != -1) killTimer(nTimerId);
487  nTimerId = startTimer(static_cast<UInt32>(CPhysicsEngine::GetSimulationClockTick() * 1000.0f));
488  }
489 
490  /****************************************/
491  /****************************************/
492 
494  m_nFrameCounter = 0;
495  m_bFastForwarding = true;
496  if(nTimerId != -1) killTimer(nTimerId);
497  nTimerId = startTimer(1);
498  }
499 
500  /****************************************/
501  /****************************************/
502 
504  m_bFastForwarding = false;
505  if(nTimerId != -1) killTimer(nTimerId);
506  nTimerId = -1;
507  }
508 
509  /****************************************/
510  /****************************************/
511 
513  if(!m_cSimulator.IsExperimentFinished()) {
514  m_cSimulator.UpdateSpace();
515  if(m_bFastForwarding) {
516  /* Frame dropping happens only in fast-forward */
517  m_nFrameCounter = m_nFrameCounter % m_nDrawFrameEvery;
518  if(m_nFrameCounter == 0) {
519  update();
520  }
521  ++m_nFrameCounter;
522  } else {
523  update();
524  }
525  m_cCamera.UpdateTimeline();
526  emit StepDone(m_cSpace.GetSimulationClock());
527  }
528  else {
529  PauseExperiment();
530  emit ExperimentDone();
531  }
532  }
533 
534  /****************************************/
535  /****************************************/
536 
538  m_cSimulator.Reset();
539  m_cCamera.Reset();
540  delete m_pcGroundTexture;
541  if(m_bUsingFloorTexture) delete m_pcFloorTexture;
542  initializeGL();
543  update();
544  }
545 
546  /****************************************/
547  /****************************************/
548 
550  m_nDrawFrameEvery = n_every;
551  }
552 
553  /****************************************/
554  /****************************************/
555 
556  void CQTOpenGLWidget::SetGrabFrame(bool b_grab_on) {
557  m_sFrameGrabData.GUIGrabbing = b_grab_on;
558  }
559 
560  /****************************************/
561  /****************************************/
562 
563  void CQTOpenGLWidget::SetCamera(int n_camera) {
564  m_cCamera.SetActivePlacement(n_camera);
565  update();
566  QToolTip::showText(pos() + geometry().center(), QString("Current camera: #%1").arg(n_camera+1));
567  }
568 
569  /****************************************/
570  /****************************************/
571 
573  m_cCamera.GetActivePlacement().LensFocalLength = f_length / 1000.0f;
575  update();
576  }
577 
578  /****************************************/
579  /****************************************/
580 
581  void CQTOpenGLWidget::KeyPressed(QKeyEvent* pc_event) {
582  switch(pc_event->key()) {
583  case Qt::Key_W:
584  case Qt::Key_Up:
585  /* Forwards */
586  m_mapPressedKeys[DIRECTION_FORWARDS] = true;
587  reactToKeyEvent();
588  break;
589  case Qt::Key_S:
590  case Qt::Key_Down:
591  /* Backwards */
592  m_mapPressedKeys[DIRECTION_BACKWARDS] = true;
593  reactToKeyEvent();
594  break;
595  case Qt::Key_A:
596  case Qt::Key_Left:
597  /* Left */
598  m_mapPressedKeys[DIRECTION_LEFT] = true;
599  reactToKeyEvent();
600  break;
601  case Qt::Key_D:
602  case Qt::Key_Right:
603  /* Right */
604  m_mapPressedKeys[DIRECTION_RIGHT] = true;
605  reactToKeyEvent();
606  break;
607  case Qt::Key_E:
608  /* Up */
609  m_mapPressedKeys[DIRECTION_UP] = true;
610  reactToKeyEvent();
611  break;
612  case Qt::Key_Q:
613  /* Up */
614  m_mapPressedKeys[DIRECTION_DOWN] = true;
615  reactToKeyEvent();
616  break;
617  default:
618  /* Unknown key */
619  QOpenGLWidget::keyPressEvent(pc_event);
620  break;
621  }
622  }
623 
624  /****************************************/
625  /****************************************/
626 
627  void CQTOpenGLWidget::KeyReleased(QKeyEvent* pc_event) {
628  switch(pc_event->key()) {
629  case Qt::Key_W:
630  case Qt::Key_Up:
631  /* Forwards */
632  m_mapPressedKeys[DIRECTION_FORWARDS] = false;
633  reactToKeyEvent();
634  break;
635  case Qt::Key_S:
636  case Qt::Key_Down:
637  /* Backwards */
638  m_mapPressedKeys[DIRECTION_BACKWARDS] = false;
639  reactToKeyEvent();
640  break;
641  case Qt::Key_A:
642  case Qt::Key_Left:
643  /* Left */
644  m_mapPressedKeys[DIRECTION_LEFT] = false;
645  reactToKeyEvent();
646  break;
647  case Qt::Key_D:
648  case Qt::Key_Right:
649  /* Right */
650  m_mapPressedKeys[DIRECTION_RIGHT] = false;
651  reactToKeyEvent();
652  break;
653  case Qt::Key_E:
654  /* Up */
655  m_mapPressedKeys[DIRECTION_UP] = false;
656  reactToKeyEvent();
657  break;
658  case Qt::Key_Q:
659  /* Up */
660  m_mapPressedKeys[DIRECTION_DOWN] = false;
661  reactToKeyEvent();
662  break;
663  default:
664  /* Unknown key */
665  QOpenGLWidget::keyPressEvent(pc_event);
666  break;
667  }
668  }
669 
670  /****************************************/
671  /****************************************/
672 
674  CVector3 cArenaSize(m_cSpace.GetArenaSize());
675  CVector3 cArenaMinCorner(m_cSpace.GetArenaCenter().GetX() - cArenaSize.GetX() * 0.5f,
676  m_cSpace.GetArenaCenter().GetY() - cArenaSize.GetY() * 0.5f,
677  m_cSpace.GetArenaCenter().GetZ() - cArenaSize.GetZ() * 0.5f);
678  CVector3 cArenaMaxCorner(m_cSpace.GetArenaCenter().GetX() + cArenaSize.GetX() * 0.5f,
679  m_cSpace.GetArenaCenter().GetY() + cArenaSize.GetY() * 0.5f,
680  m_cSpace.GetArenaCenter().GetZ() + cArenaSize.GetZ() * 0.5f);
681  /* Disable lighting - no funny color effects */
682  glDisable(GL_LIGHTING);
683  /* Enable textures */
684  glEnable(GL_TEXTURE_2D);
685  /* Take care of the floor entity if necessary */
686  /* The texture covers the object like a decal */
687  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
688 #ifdef ARGOS_WITH_FREEIMAGE
689  if(m_bUsingFloorTexture) {
690  /* Use the image as texture */
691  if(m_cSpace.GetFloorEntity().HasChanged()) {
692  /* Create an image to use as texture */
693  m_pcFloorTexture->destroy();
694  m_pcFloorTexture->create();
695  m_cSpace.GetFloorEntity().SaveAsImage("/tmp/argos_floor.png");
696  m_pcFloorTexture->setData(QImage("/tmp/argos_floor.png"));
697  m_pcFloorTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,
698  QOpenGLTexture::Linear);
699  /* Clear the 'changed' flag on the floor entity */
700  m_cSpace.GetFloorEntity().ClearChanged();
701  }
702  /* Draw the floor entity along with its texture */
703  m_pcFloorTexture->bind();
704  glBegin(GL_QUADS);
705  glTexCoord2d(0.0f, 1.0f); glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), 0.0f);
706  glTexCoord2d(1.0f, 1.0f); glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), 0.0f);
707  glTexCoord2d(1.0f, 0.0f); glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), 0.0f);
708  glTexCoord2d(0.0f, 0.0f); glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), 0.0f);
709  glEnd();
710  }
711  else {
712 #endif
713  /* Wrap the texture at the edges, which in this case means that it is repeated */
714  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
715  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
716  m_pcGroundTexture->bind();
717  /* Draw the floor along with its texture */
718  glBegin(GL_QUADS);
719  glTexCoord2d(0.0f, cArenaSize.GetY()); glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), 0.0f);
720  glTexCoord2d(cArenaSize.GetX(), cArenaSize.GetY()); glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), 0.0f);
721  glTexCoord2d(cArenaSize.GetX(), 0.0f); glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), 0.0f);
722  glTexCoord2d(0.0f, 0.0f); glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), 0.0f);
723  glEnd();
724 #ifdef ARGOS_WITH_FREEIMAGE
725  }
726 #endif
727  /* Disable the textures */
728  glDisable(GL_TEXTURE_2D);
729  if(m_bShowBoundary) {
730  /* Draw walls */
731  glDisable(GL_CULL_FACE);
732  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
733  glLineWidth(10.0f);
734  glColor3f(0.0f, 0.0f, 0.0f);
735  /* This part covers the top and bottom faces (parallel to XY) */
736  glBegin(GL_QUADS);
737  /* Top face */
738  glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), cArenaMaxCorner.GetZ());
739  glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), cArenaMaxCorner.GetZ());
740  glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMaxCorner.GetZ());
741  glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMaxCorner.GetZ());
742  glEnd();
743  /* This part covers the faces (South, East, North, West) */
744  glBegin(GL_QUADS);
745  /* South face */
746  glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), cArenaMinCorner.GetZ());
747  glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), cArenaMaxCorner.GetZ());
748  glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMaxCorner.GetZ());
749  glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMinCorner.GetZ());
750  /* East face */
751  glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), cArenaMinCorner.GetZ());
752  glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), cArenaMinCorner.GetZ());
753  glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), cArenaMaxCorner.GetZ());
754  glVertex3d(cArenaMinCorner.GetX(), cArenaMinCorner.GetY(), cArenaMaxCorner.GetZ());
755  /* North face */
756  glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), cArenaMinCorner.GetZ());
757  glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMinCorner.GetZ());
758  glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMaxCorner.GetZ());
759  glVertex3d(cArenaMaxCorner.GetX(), cArenaMinCorner.GetY(), cArenaMaxCorner.GetZ());
760  /* West face */
761  glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMinCorner.GetZ());
762  glVertex3d(cArenaMinCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMaxCorner.GetZ());
763  glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMaxCorner.GetZ());
764  glVertex3d(cArenaMaxCorner.GetX(), cArenaMaxCorner.GetY(), cArenaMinCorner.GetZ());
765  glEnd();
766  glLineWidth(1.0f);
767  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
768  glEnable(GL_CULL_FACE);
769  }
770  /* Restore lighting */
771  glEnable(GL_LIGHTING);
772  }
773 
774  /****************************************/
775  /****************************************/
776 
778  }
779 
780  /****************************************/
781  /****************************************/
782 
783  void CQTOpenGLWidget::timerEvent(QTimerEvent* pc_event) {
784  StepExperiment();
785  }
786 
787  /****************************************/
788  /****************************************/
789 
790  void CQTOpenGLWidget::mousePressEvent(QMouseEvent* pc_event) {
791  /*
792  * Mouse press without shift
793  * Either pure press, or press + CTRL
794  */
795  if(! (pc_event->modifiers() & Qt::ShiftModifier)) {
796  if(! (pc_event->modifiers() & Qt::AltModifier)) {
797  m_bMouseGrabbed = true;
798  m_cMouseGrabPos = pc_event->pos();
799  }
800  else {
801  m_cUserFunctions.MouseKeyPressed(pc_event);
802  }
803  }
804  /*
805  * Mouse press with shift
806  */
807  else {
808  m_bMouseGrabbed = false;
809  SelectInScene(pc_event->pos().x(),
810  pc_event->pos().y());
811  }
812  }
813 
814  /****************************************/
815  /****************************************/
816 
817  void CQTOpenGLWidget::mouseReleaseEvent(QMouseEvent* pc_event) {
818  /*
819  * Mouse grabbed, selected entity, CTRL pressed
820  */
821  if(m_bMouseGrabbed &&
822  m_sSelectionInfo.IsSelected &&
823  (pc_event->modifiers() & Qt::ControlModifier)) {
824  /* Treat selected entity as an embodied entity */
825  auto* pcEntity = dynamic_cast<CEmbodiedEntity*>(m_sSelectionInfo.Entity);
826  if(pcEntity == nullptr) {
827  /* Treat selected entity as a composable entity with an embodied component */
828  auto* pcCompEntity = dynamic_cast<CComposableEntity*>(m_sSelectionInfo.Entity);
829  if(pcCompEntity != nullptr && pcCompEntity->HasComponent("body")) {
830  pcEntity = &pcCompEntity->GetComponent<CEmbodiedEntity>("body");
831  }
832  else {
833  /* All conversions failed, get out */
834  m_bMouseGrabbed = false;
835  return;
836  }
837  }
838  /*
839  * If we get here, pcEntity is set to a non-NULL value
840  * Move the entity to the wanted place
841  */
842  /* Create a plane coincident with the world XY plane, centered at the entity position */
843  CPlane cXYPlane(pcEntity->GetOriginAnchor().Position, CVector3::Z);
844  /* Create a ray from the image pixel to the world */
845  CRay3 cMouseRay =
846  RayFromWindowCoord(pc_event->pos().x(),
847  pc_event->pos().y());
848  /* Calculate the new entity position as the intersection of the projected mouse position
849  with the plane created before */
850  CVector3 cNewPos;
851  if(cMouseRay.Intersects(cXYPlane, cNewPos)) {
852  CVector3 cOldPos(pcEntity->GetOriginAnchor().Position);
853  if(pcEntity->MoveTo(cNewPos, pcEntity->GetOriginAnchor().Orientation)) {
854  m_cUserFunctions.EntityMoved(pcEntity->GetRootEntity(), cOldPos, cNewPos);
855  }
856  /* Entity moved, redraw */
857  update();
858  }
859  }
860  else {
861  m_cUserFunctions.MouseKeyReleased(pc_event);
862  }
863  /*
864  * Mouse was grabbed, button released -> ungrab mouse
865  */
866  m_bMouseGrabbed = false;
867  }
868 
869  /****************************************/
870  /****************************************/
871 
872  void CQTOpenGLWidget::mouseMoveEvent(QMouseEvent* pc_event) {
873  /*
874  * Moving while mouse grabbed -> camera movement
875  */
876  if(m_bMouseGrabbed) {
877  if(! (pc_event->modifiers() & Qt::ControlModifier)) {
878  /*
879  * Camera movement
880  */
881  if(pc_event->buttons() == Qt::LeftButton) {
882  if (m_bInvertMouse) m_cCamera.Rotate( pc_event->pos() - m_cMouseGrabPos);
883  else m_cCamera.Rotate( m_cMouseGrabPos - pc_event->pos());
884  m_cMouseGrabPos = pc_event->pos();
885  update();
886  }
887  else if(pc_event->buttons() == Qt::RightButton) {
888  QPoint cDelta(pc_event->pos() - m_cMouseGrabPos);
889  m_cCamera.Move(-cDelta.y(), cDelta.x(), 0);
890  m_cMouseGrabPos = pc_event->pos();
891  update();
892  }
893  else if(pc_event->buttons() == Qt::MiddleButton) {
894  QPoint cDelta(pc_event->pos() - m_cMouseGrabPos);
895  m_cCamera.Move(0, 0, cDelta.y());
896  m_cMouseGrabPos = pc_event->pos();
897  update();
898  }
899  }
900  }
901  else {
902  m_cUserFunctions.MouseMoved(pc_event);
903  }
904  }
905 
906  /****************************************/
907  /****************************************/
908 
909  void CQTOpenGLWidget::wheelEvent(QWheelEvent *pc_event) {
910  if(m_sSelectionInfo.IsSelected && (pc_event->modifiers() & Qt::ControlModifier)) {
911  /* Treat selected entity as an embodied entity */
912  auto* pcEntity = dynamic_cast<CEmbodiedEntity*>(m_sSelectionInfo.Entity);
913  if(pcEntity == nullptr) {
914  /* Treat selected entity as a composable entity with an embodied component */
915  auto* pcCompEntity = dynamic_cast<CComposableEntity*>(m_sSelectionInfo.Entity);
916  if(pcCompEntity != nullptr && pcCompEntity->HasComponent("body")) {
917  pcEntity = &pcCompEntity->GetComponent<CEmbodiedEntity>("body");
918  }
919  else {
920  return;
921  }
922  }
923  /*
924  * If we get here, pcEntity is set to a non-NULL value
925  * Rotate the entity
926  */
927  CDegrees cDegrees(pc_event->angleDelta().y() / 8);
928  CQuaternion cRotation(ToRadians(cDegrees), CVector3::Z);
929  CQuaternion cOldOrientation(pcEntity->GetOriginAnchor().Orientation);
930  CQuaternion cNewOrientation(cOldOrientation * cRotation);
931  if(pcEntity->MoveTo(pcEntity->GetOriginAnchor().Position, cNewOrientation)) {
932  m_cUserFunctions.EntityRotated(pcEntity->GetRootEntity(), cOldOrientation, cNewOrientation);
933  }
934  /* entity updated, redraw the scene */
935  update();
936  }
937  }
938 
939  /****************************************/
940  /****************************************/
941 
942  void CQTOpenGLWidget::keyPressEvent(QKeyEvent* pc_event) {
943  m_cUserFunctions.KeyPressed(pc_event);
944  }
945 
946  /****************************************/
947  /****************************************/
948 
949  void CQTOpenGLWidget::keyReleaseEvent(QKeyEvent* pc_event) {
950  m_cUserFunctions.KeyReleased(pc_event);
951  }
952 
953  /****************************************/
954  /****************************************/
955 
957  SInt32 nForwardsBackwards = 0;
958  SInt32 nSideways = 0;
959  SInt32 nUpDown = 0;
960 
961  if(m_mapPressedKeys[DIRECTION_UP]) nUpDown++;
962  if(m_mapPressedKeys[DIRECTION_DOWN]) nUpDown--;
963  if(m_mapPressedKeys[DIRECTION_LEFT]) nSideways++;
964  if(m_mapPressedKeys[DIRECTION_RIGHT]) nSideways--;
965  if(m_mapPressedKeys[DIRECTION_FORWARDS]) nForwardsBackwards++;
966  if(m_mapPressedKeys[DIRECTION_BACKWARDS]) nForwardsBackwards--;
967 
968  if(nForwardsBackwards != 0 ||
969  nSideways != 0 ||
970  nUpDown != 0) {
971  m_cCamera.Move(15 * nForwardsBackwards,
972  15 * nSideways,
973  15 * nUpDown);
974  update();
975  }
976  }
977 
978  /****************************************/
979  /****************************************/
980 
981  void CQTOpenGLWidget::resizeEvent(QResizeEvent* pc_event) {
982  /* Call parent's resize event handler */
983  QOpenGLWidget::resizeEvent(pc_event);
984  /* Show new window size */
985  QToolTip::showText(pos() + geometry().center(), QString("Size: %1 x %2").arg(pc_event->size().width()).arg(pc_event->size().height()));
986  }
987 
988  /****************************************/
989  /****************************************/
990 
992  if(NodeExists(t_tree, "frame_grabbing")) {
993  TConfigurationNode& tNode = GetNode(t_tree, "frame_grabbing");
994  std::string strBuffer;
995  /* Parse directory, removing trailing '/' */
996  strBuffer = ".";
997  GetNodeAttributeOrDefault(tNode, "directory", strBuffer, strBuffer);
998  size_t unEndPos = strBuffer.find_last_not_of("/ \t");
999  if(unEndPos != std::string::npos) {
1000  strBuffer = strBuffer.substr(0, unEndPos+1);
1001  }
1002  Directory = strBuffer.c_str();
1003  QDir cDirectory(Directory);
1004  if(!cDirectory.exists()) {
1005  THROW_ARGOSEXCEPTION("QTOpenGL: frame grabbing directory \"" << strBuffer << "\" does not exist. Create it first!");
1006  }
1007  /* Parse base name */
1008  strBuffer = "frame_";
1009  GetNodeAttributeOrDefault(tNode, "base_name", strBuffer, strBuffer);
1010  BaseName = strBuffer.c_str();
1011  /* Parse format */
1012  strBuffer = "png";
1013  GetNodeAttributeOrDefault(tNode, "format", strBuffer, strBuffer);
1014  Format = strBuffer.c_str();
1015  /* Parse quality */
1016  GetNodeAttributeOrDefault(tNode, "quality", Quality, Quality);
1017 
1018  /* Parse headless grabbing */
1020  "headless_grabbing",
1023  /* Parse headless frame size */
1024  strBuffer = "1600x1200";
1026  "headless_frame_size",
1027  strBuffer,
1028  strBuffer);
1029  uint dims[2];
1030  ParseValues(strBuffer, 2, dims, 'x');
1031  Size = QSize(dims[0], dims[1]);
1032 
1033  /* Parse headless frame rate */
1035  "headless_frame_rate",
1038  }
1039  }
1040 
1041  /****************************************/
1042  /****************************************/
1043 
1044 }
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
signed int SInt32
32-bit signed integer.
Definition: datatypes.h:93
unsigned int UInt32
32-bit unsigned integer.
Definition: datatypes.h:97
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
TConfigurationNode & GetNode(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns the first of its child nodes with the wanted name.
bool GetClosestEmbodiedEntityIntersectedByRay(SEmbodiedEntityIntersectionItem &s_item, const CRay3 &c_ray)
Returns the closest intersection with an embodied entity to the ray start.
void GetNodeAttributeOrDefault(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer, const T &t_default)
Returns the value of a node's attribute, or the passed default value.
void ParseValues(std::istream &str_input, UInt32 un_num_fields, T *pt_field_buffer, const char ch_delimiter='\n')
CDegrees ToDegrees(const CRadians &c_radians)
Converts CRadians to CDegrees.
Definition: angles.h:489
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
bool NodeExists(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns true if one of its child nodes has the wanted name.
CRadians ToRadians(const CDegrees &c_degrees)
Converts CDegrees to CRadians.
Definition: angles.h:498
Basic class for an entity that contains other entities.
CEntity & GetComponent(const std::string &str_component)
Returns the component with the passed string label.
An entity that contains a pointer to the user-defined controller.
std::vector< CVector3 > & GetIntersectionPoints()
Returns the list of intersection points.
std::vector< std::pair< bool, CRay3 > > & GetCheckedRays()
Returns the list of checked rays.
This entity is a link to a body in the physics engine.
const SBoundingBox & GetBoundingBox() const
Returns the bounding box of this embodied entity.
const SAnchor & GetOriginAnchor() const
Returns a const reference to the origin anchor associated to this entity.
The basic entity type.
Definition: entity.h:90
std::vector< CEntity * > TVector
A vector of entities.
Definition: entity.h:97
CEntity & GetRootEntity()
Returns the root entity containing this entity.
Definition: entity.cpp:115
bool HasChanged() const
Returns true if the floor color has changed.
Definition: floor_entity.h:113
void ClearChanged()
Marks the floor color as not changed.
Definition: floor_entity.h:129
const CQuaternion & GetOrientation() const
const CVector3 & GetPosition() const
static Real GetSimulationClockTick()
Returns the simulation clock tick.
CQuaternion Orientation
The orientation of the anchor wrt the global coordinate system.
Definition: physics_model.h:53
CVector3 Position
The position of the anchor wrt the global coordinate system.
Definition: physics_model.h:51
The core class of ARGOS.
Definition: simulator.h:62
bool IsExperimentFinished() const
Returns true if the experiment has finished.
Definition: simulator.cpp:288
void UpdateSpace()
Performs an update step of the space.
Definition: simulator.cpp:280
void Reset()
Resets the experiment.
Definition: simulator.cpp:179
CFloorEntity & GetFloorEntity()
Returns the floor entity.
Definition: space.h:239
UInt32 GetSimulationClock() const
Returns the current value of the simulation clock.
Definition: space.h:345
const CVector3 & GetArenaSize() const
Returns the arena size.
Definition: space.h:371
const CVector3 & GetArenaCenter() const
Returns the arena center.
Definition: space.h:389
CEntity::TVector & GetRootEntityVector()
Returns a vector of all the root entities in the space.
Definition: space.h:150
The exception that wraps all errors in ARGoS.
It defines the basic type CRadians, used to store an angle value in radians.
Definition: angles.h:42
It defines the basic type CDegrees, used to store an angle value in degrees.
Definition: angles.h:288
Real GetValue() const
Returns the value in degrees.
Definition: angles.h:322
void ToEulerAngles(CRadians &c_z_angle, CRadians &c_y_angle, CRadians &c_x_angle) const
Definition: quaternion.h:172
bool Intersects(const CPlane &c_plane, CVector3 &c_point) const
Definition: ray3.cpp:15
A 3D vector class.
Definition: vector3.h:31
Real GetX() const
Returns the x coordinate of this vector.
Definition: vector3.h:105
Real GetY() const
Returns the y coordinate of this vector.
Definition: vector3.h:121
static const CVector3 Z
The z axis.
Definition: vector3.h:42
Real GetZ() const
Returns the z coordinate of this vector.
Definition: vector3.h:137
void SetActivePlacement(UInt32 n_index)
void Move(SInt32 n_forwards_backwards, SInt32 n_sideways, SInt32 n_up_down)
SPlacement & GetActivePlacement()
void Rotate(const QPoint &c_delta)
CDegrees YFieldOfView
The focal length of the camera.
Real LensFocalLength
The focal length of the lens (if this was a real camera)
void CalculateYFieldOfView()
Calculates the value of YFieldOfView.
const QString & GetTextureDir() const
The QTOpenGL user functions.
virtual void EntityMoved(CEntity &c_entity, const CVector3 &c_old_pos, const CVector3 &c_new_pos)
Called every time an entity is moved.
virtual void EntityDeselected(CEntity &c_entity)
Called every time an entity is deselected.
virtual void MouseKeyPressed(QMouseEvent *pc_event)
Called when a mouse key is pressed.
virtual void EntityRotated(CEntity &c_entity, const CQuaternion &c_old_orientation, const CQuaternion &c_new_orientation)
Called every time an entity is rotated.
virtual void MouseMoved(QMouseEvent *pc_event)
Called when the mouse is moved.
virtual void KeyPressed(QKeyEvent *pc_event)
Called when a key press event occurs.
virtual void KeyReleased(QKeyEvent *pc_event)
Called when a key release event occurs.
virtual void Call(CEntity &c_entity)
Calls a user method for the given entity.
virtual void DrawInWorld()
Drawing hook executed after all objects have been drawn.
virtual void EntitySelected(CEntity &c_entity)
Called every time an entity is selected.
virtual void DrawOverlay(QPainter &c_painter)
Drawing hook to put graphics on top of the OpenGL window.
virtual void MouseKeyReleased(QMouseEvent *pc_event)
Called when a mouse key is released.
CEntity * GetSelectedEntity()
Returns the currently selected entity, or NULL if none is selected.
void StepExperiment()
Executes one experiment time step.
CVector3 GetWindowCoordInWorld(int n_x, int n_y)
Returns the position in the world corresponding to the given window coordinate.
virtual void mouseReleaseEvent(QMouseEvent *pc_event)
virtual void wheelEvent(QWheelEvent *pc_event)
void KeyPressed(QKeyEvent *pc_event)
Handles key press events.
CRay3 RayFromWindowCoord(int n_x, int n_y)
Casts a ray from the given window coordinate.
virtual ~CQTOpenGLWidget()
Class destructor.
void SelectEntity(CEntity &c_entity)
Selects the passed entity.
void KeyReleased(QKeyEvent *pc_event)
Handles key release events.
void SetCameraFocalLength(double f_length)
Sets the focal length of the current camera.
void FastForwardExperiment()
Fast forwards the experiment.
void EntitySelected(CEntity *pc_entity)
Emitted when an entity is selected.
void DrawRays(CControllableEntity &c_entity)
Draws a ray.
void PlayExperiment()
Plays the experiment.
void ResetExperiment()
Resets the state of the experiment to its state right after initialization.
virtual void mouseMoveEvent(QMouseEvent *pc_event)
void EntityDeselected(CEntity *pc_entity)
Emitted when an entity is deselected.
void DrawEntity(CPositionalEntity &c_entity)
Draws a positional entity.
void DeselectEntity()
Deselects the currently selected entity.
void SetGrabFrame(bool b_grab_on)
Toggles frame grabbing.
virtual void keyReleaseEvent(QKeyEvent *pc_event)
void DrawBoundingBox(CEmbodiedEntity &c_entity)
Draws the bounding box of an embodied entity.
virtual void keyPressEvent(QKeyEvent *pc_event)
void SetDrawFrameEvery(int n_every)
When fast-forwarding, sets every how many steps a frame must be drawn.
void SelectInScene(UInt32 un_x, UInt32 un_y)
Selects the entity closest to the camera at the given screen coordinates.
virtual void paintGL()
Logic for scene drawing.
CQTOpenGLWidget(QWidget *pc_parent, CQTOpenGLMainWindow &c_main_window, CQTOpenGLUserFunctions &c_user_functions)
Class constructor.
void ExperimentDone()
Emitted when the experiment is finished.
virtual void initializeGL()
Called when the GL context must be initialized.
virtual void mousePressEvent(QMouseEvent *pc_event)
void PauseExperiment()
Pauses the experiment.
virtual void resizeEvent(QResizeEvent *pc_event)
void StepDone(int n_step)
Emitted whenever a time step has been executed.
void SetCamera(int n_camera)
Sets the current camera in use.
virtual void timerEvent(QTimerEvent *pc_event)
void Init(TConfigurationNode &t_tree)