ARGoS 3
A parallel, multi-engine simulator for swarm robotics
qtopengl_widget.cpp
Go to the documentation of this file.
1
7#include "qtopengl_widget.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
32namespace 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();
163 m_cUserFunctions.Call(**itEntities);
164 glPopMatrix();
165 }
166 /* Draw the selected object, if necessary */
167 if(m_sSelectionInfo.IsSelected) {
168 glPushMatrix();
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
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 {
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;
588 break;
589 case Qt::Key_S:
590 case Qt::Key_Down:
591 /* Backwards */
592 m_mapPressedKeys[DIRECTION_BACKWARDS] = true;
594 break;
595 case Qt::Key_A:
596 case Qt::Key_Left:
597 /* Left */
598 m_mapPressedKeys[DIRECTION_LEFT] = true;
600 break;
601 case Qt::Key_D:
602 case Qt::Key_Right:
603 /* Right */
604 m_mapPressedKeys[DIRECTION_RIGHT] = true;
606 break;
607 case Qt::Key_E:
608 /* Up */
609 m_mapPressedKeys[DIRECTION_UP] = true;
611 break;
612 case Qt::Key_Q:
613 /* Up */
614 m_mapPressedKeys[DIRECTION_DOWN] = true;
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;
634 break;
635 case Qt::Key_S:
636 case Qt::Key_Down:
637 /* Backwards */
638 m_mapPressedKeys[DIRECTION_BACKWARDS] = false;
640 break;
641 case Qt::Key_A:
642 case Qt::Key_Left:
643 /* Left */
644 m_mapPressedKeys[DIRECTION_LEFT] = false;
646 break;
647 case Qt::Key_D:
648 case Qt::Key_Right:
649 /* Right */
650 m_mapPressedKeys[DIRECTION_RIGHT] = false;
652 break;
653 case Qt::Key_E:
654 /* Up */
655 m_mapPressedKeys[DIRECTION_UP] = false;
657 break;
658 case Qt::Key_Q:
659 /* Up */
660 m_mapPressedKeys[DIRECTION_DOWN] = false;
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
779
780 /****************************************/
781 /****************************************/
782
783 void CQTOpenGLWidget::timerEvent(QTimerEvent* pc_event) {
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}
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
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
The namespace containing all the ARGoS related code.
Definition ci_actuator.h:12
RETURN_VALUE CallEntityOperation(PLUGIN &t_plugin, CEntity &c_entity)
Calls the operation corresponding to the given context and operand Skips the function call if the ope...
Definition entity.h:418
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.
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.
CRadians ToRadians(const CDegrees &c_degrees)
Converts CDegrees to CRadians.
Definition angles.h:498
Basic class for an entity that contains other entities.
An entity that contains a pointer to the user-defined controller.
std::vector< std::pair< bool, CRay3 > > & GetCheckedRays()
Returns the list of checked rays.
std::vector< CVector3 > & GetIntersectionPoints()
Returns the list of intersection points.
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.
void ClearChanged()
Marks the floor color as not changed.
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.
CVector3 Position
The position of the anchor wrt the global coordinate system.
The core class of ARGOS.
Definition simulator.h:62
bool IsExperimentFinished() const
Returns true if the experiment has finished.
void UpdateSpace()
Performs an update step of the space.
void Reset()
Resets the experiment.
const CVector3 & GetArenaCenter() const
Returns the arena center.
Definition space.h:389
const CVector3 & GetArenaSize() const
Returns the arena size.
Definition space.h:371
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
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)