LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / modelview / modelviewgadgetwidget.cpp
blob6e5a666fbdcc2e6d229f0b20666faa2b3ab6bc13
1 /**
2 ******************************************************************************
4 * @file modelviewgadgetwidget.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
7 * @{
8 * @addtogroup ModelViewPlugin ModelView Plugin
9 * @{
10 * @brief A gadget that displays a 3D representation of the UAV
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "QtDebug"
28 #ifdef __APPLE__
29 #include "OpenGL/OpenGL.h"
30 #endif
31 #include "modelviewgadgetwidget.h"
32 #include "extensionsystem/pluginmanager.h"
33 #include "glc_context.h"
34 #include "glc_exception.h"
35 #include "glc_openglexception.h"
36 #include "viewport/glc_userinput.h"
38 #include <iostream>
40 ModelViewGadgetWidget::ModelViewGadgetWidget(QWidget *parent)
41 : QGLWidget(new GLC_Context(QGLFormat(QGL::SampleBuffers)), parent)
42 , m_Light()
43 , m_World()
44 , m_GlView()
45 , m_MoverController()
46 , m_ModelBoundingBox()
47 , m_MotionTimer()
48 , acFilename()
49 , bgFilename()
50 , vboEnable(false)
52 connect(&m_GlView, SIGNAL(updateOpenGL()), this, SLOT(updateGL()));
53 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
55 m_Light.setPosition(4000.0, 40000.0, 80000.0);
56 // m_GlView.setBackgroundColor(Qt::white);
57 m_Light.setAmbientColor(Qt::lightGray);
59 m_GlView.cameraHandle()->setDefaultUpVector(glc::Z_AXIS);
60 m_GlView.cameraHandle()->setRearView();
62 QColor repColor;
63 repColor.setRgbF(1.0, 0.11372, 0.11372, 0.0);
64 m_MoverController = GLC_Factory::instance()->createDefaultMoverController(repColor, &m_GlView);
66 CreateScene();
67 // Get required UAVObjects
68 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
69 UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
70 attState = AttitudeState::GetInstance(objManager);
72 connect(&m_MotionTimer, SIGNAL(timeout()), this, SLOT(updateAttitude()));
75 ModelViewGadgetWidget::~ModelViewGadgetWidget()
79 void ModelViewGadgetWidget::setAcFilename(QString acf)
81 if (QFile::exists(acf)) {
82 acFilename = acf;
83 } else {
84 acFilename = acf = ":/modelview/models/warning_sign.obj";
85 m_GlView.cameraHandle()->setFrontView(); // set to front camera to see/read the warning sign
89 void ModelViewGadgetWidget::setBgFilename(QString bgf)
91 if (QFile::exists(bgFilename)) {
92 bgFilename = bgf;
93 } else {
94 qDebug() << "file " << bgf << " doesn't exists";
95 bgFilename = ":/modelview/models/black.jpg"; // will put a black background if there's no background
99 void ModelViewGadgetWidget::setVboEnable(bool eVbo)
101 vboEnable = eVbo;
102 m_World.collection()->setVboUsage(vboEnable);
105 //// Public funcitons ////
106 void ModelViewGadgetWidget::reloadScene()
108 CreateScene();
111 //// Private functions ////
112 void ModelViewGadgetWidget::initializeGL()
114 // For VSYNC problem under Mac OS X
115 #if defined(Q_OS_MAC)
116 const GLint swapInterval = 1;
117 CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval);
118 #endif
120 // OpenGL initialization
121 m_GlView.initGl();
122 // Reframe the scene
123 m_GlView.reframe(m_ModelBoundingBox);
125 glEnable(GL_NORMALIZE);
126 // Enable antialiasing
127 glEnable(GL_MULTISAMPLE);
129 m_MotionTimer.start(100);
130 setFocusPolicy(Qt::StrongFocus); // keyboard capture for camera switching
133 void ModelViewGadgetWidget::paintGL()
135 try {
136 // Clear screen
137 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
139 // OpenGL error handler
141 GLenum error = glGetError();
142 if (error != GL_NO_ERROR) {
143 GLC_OpenGlException OpenGlException("ModelViewGadgetWidget::paintGL() ", error);
144 throw(OpenGlException);
148 // Load identity matrix
149 GLC_Context::current()->glcLoadIdentity();
151 // Enable antialiasing
152 glEnable(GL_MULTISAMPLE);
154 // Calculate camera depth of view
155 m_GlView.setDistMinAndMax(m_World.boundingBox());
157 // define view matrix
158 m_GlView.glExecuteCam();
159 m_Light.glExecute();
161 // Display the collection of GLC_Object
162 m_World.render(0, glc::ShadingFlag);
163 m_World.render(0, glc::TransparentRenderFlag);
165 // Display UI Info (orbit circle)
166 m_MoverController.drawActiveMoverRep();
167 } catch(GLC_Exception &e) {
168 qDebug() << e.what();
172 void ModelViewGadgetWidget::resizeGL(int width, int height)
174 m_GlView.setWinGLSize(width, height); // Compute window aspect ratio
175 // OpenGL error handler
177 GLenum error = glGetError();
178 if (error != GL_NO_ERROR) {
179 GLC_OpenGlException OpenGlException("ModelViewGadgetWidget::resizeGL() ", error);
180 throw(OpenGlException);
185 // Create GLC_Object to display
186 void ModelViewGadgetWidget::CreateScene()
188 // put a black background if the 3D model is invalid or if the background image is also invalid
189 if (acFilename == ":/modelview/models/warning_sign.obj" or !QFile::exists(bgFilename)) {
190 bgFilename = ":/modelview/models/black.jpg";
194 try {
195 m_GlView.loadBackGroundImage(bgFilename);
196 } catch(GLC_Exception e) {
197 qDebug("ModelView: background image file loading failed.");
200 try {
201 if (QFile::exists(acFilename)) {
202 QFile aircraft(acFilename);
203 m_World = GLC_Factory::instance()->createWorldFromFile(aircraft);
204 m_ModelBoundingBox = m_World.boundingBox();
205 m_GlView.reframe(m_ModelBoundingBox); // center 3D model in the scene
206 } else {
207 qDebug("ModelView: aircraft file not found.");
209 } catch(GLC_Exception e) {
210 qDebug("ModelView: aircraft file loading failed.");
214 void ModelViewGadgetWidget::wheelEvent(QWheelEvent *e)
216 double delta = m_GlView.cameraHandle()->distEyeTarget() - (e->delta() / 4);
218 m_GlView.cameraHandle()->setDistEyeTarget(delta);
219 m_GlView.setDistMinAndMax(m_World.boundingBox());
222 void ModelViewGadgetWidget::mousePressEvent(QMouseEvent *e)
224 GLC_UserInput userInput(e->x(), e->y());
226 if (m_MoverController.hasActiveMover()) {
227 return;
230 switch (e->button()) {
231 case (Qt::LeftButton):
232 m_MotionTimer.stop();
233 m_MoverController.setActiveMover(GLC_MoverController::TurnTable, userInput);
234 updateGL();
235 break;
236 case (Qt::RightButton):
237 printf("VBO enabled: %s, VBO supported: %s, VBO used: %s\n",
238 vboEnable ? "yes" : "no",
239 GLC_State::vboSupported() ? "yes" : "no",
240 GLC_State::vboUsed() ? "yes" : "no");
241 printf("Renderer - %s \n", (char *)glGetString(GL_RENDERER));
242 printf("Extensions - %s\n", (char *)glGetString(GL_EXTENSIONS));
243 break;
244 default:
245 break;
249 void ModelViewGadgetWidget::mouseMoveEvent(QMouseEvent *e)
251 GLC_UserInput userInput(e->x(), e->y());
253 if (not m_MoverController.hasActiveMover()) {
254 return;
256 m_MoverController.move(userInput);
257 m_GlView.setDistMinAndMax(m_World.boundingBox());
258 updateGL();
261 void ModelViewGadgetWidget::mouseReleaseEvent(QMouseEvent *)
263 if (not m_MoverController.hasActiveMover()) {
264 return;
266 m_MoverController.setNoMover();
267 m_MotionTimer.start();
268 updateGL();
271 void ModelViewGadgetWidget::keyPressEvent(QKeyEvent *e) // switch between camera
273 if (e->key() == Qt::Key_1) {
274 m_GlView.cameraHandle()->setIsoView();
275 updateGL();
277 if (e->key() == Qt::Key_2) {
278 m_GlView.cameraHandle()->setFrontView();
279 updateGL();
281 if (e->key() == Qt::Key_3) {
282 m_GlView.cameraHandle()->setIsoView();
283 m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(90));
284 updateGL();
286 if (e->key() == Qt::Key_4) {
287 m_GlView.cameraHandle()->setLeftView();
288 updateGL();
290 if (e->key() == Qt::Key_5) {
291 m_GlView.cameraHandle()->setTopView();
292 m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(180));
293 updateGL();
295 if (e->key() == Qt::Key_6) {
296 m_GlView.cameraHandle()->setRightView();;
297 updateGL();
299 if (e->key() == Qt::Key_7) {
300 m_GlView.cameraHandle()->setIsoView();
301 m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(-90));
302 updateGL();
304 if (e->key() == Qt::Key_8) {
305 m_GlView.cameraHandle()->setRearView();;
306 updateGL();
308 if (e->key() == Qt::Key_9) {
309 m_GlView.cameraHandle()->setIsoView();
310 m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(180));
311 updateGL();
313 if (e->key() == Qt::Key_0) {
314 m_GlView.cameraHandle()->setBottomView();
315 m_GlView.cameraHandle()->rotateAroundTarget(glc::Z_AXIS, glc::toRadian(180));
316 updateGL();
320 //////////////////////////////////////////////////////////////////////
321 // Private slots Functions
322 //////////////////////////////////////////////////////////////////////
323 void ModelViewGadgetWidget::updateAttitude()
325 AttitudeState::DataFields data = attState->getData(); // get attitude data
326 GLC_StructOccurence *rootObject = m_World.rootOccurence(); // get the full 3D model
327 double x = data.q3;
328 double y = data.q2;
329 double z = data.q4;
330 double w = data.q1;
332 if (w == 0.0) {
333 w = 1.0;
335 // create and gives the product of 2 4x4 matrices to get the rotation of the 3D model's matrix
336 QMatrix4x4 m1;
337 m1.setRow(0, QVector4D(w, z, -y, x));
338 m1.setRow(1, QVector4D(-z, w, x, y));
339 m1.setRow(2, QVector4D(y, -x, w, z));
340 m1.setRow(3, QVector4D(-x, -y, -z, w));
341 QMatrix4x4 m2;
342 m2.setRow(0, QVector4D(w, z, -y, -x));
343 m2.setRow(1, QVector4D(-z, w, x, -y));
344 m2.setRow(2, QVector4D(y, -x, w, -z));
345 m2.setRow(3, QVector4D(x, y, z, w));
346 QMatrix4x4 m0 = m1 * m2;
347 // convert QMatrix4x4 to GLC_Matrix4x4
348 GLC_Matrix4x4 rootObjectRotation(m0.data());
349 rootObject->structInstance()->setMatrix(rootObjectRotation);
350 rootObject->updateChildrenAbsoluteMatrix();
351 updateGL();