2 ******************************************************************************
4 * @file modelviewgadgetwidget.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup ModelViewPlugin ModelView Plugin
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
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
29 #include "OpenGL/OpenGL.h"
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"
40 ModelViewGadgetWidget::ModelViewGadgetWidget(QWidget
*parent
)
41 : QGLWidget(new GLC_Context(QGLFormat(QGL::SampleBuffers
)), parent
)
46 , m_ModelBoundingBox()
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();
63 repColor
.setRgbF(1.0, 0.11372, 0.11372, 0.0);
64 m_MoverController
= GLC_Factory::instance()->createDefaultMoverController(repColor
, &m_GlView
);
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
)) {
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
)) {
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
)
102 m_World
.collection()->setVboUsage(vboEnable
);
105 //// Public funcitons ////
106 void ModelViewGadgetWidget::reloadScene()
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
);
120 // OpenGL initialization
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()
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();
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";
195 m_GlView
.loadBackGroundImage(bgFilename
);
196 } catch(GLC_Exception e
) {
197 qDebug("ModelView: background image file loading failed.");
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
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()) {
230 switch (e
->button()) {
231 case (Qt::LeftButton
):
232 m_MotionTimer
.stop();
233 m_MoverController
.setActiveMover(GLC_MoverController::TurnTable
, userInput
);
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
));
249 void ModelViewGadgetWidget::mouseMoveEvent(QMouseEvent
*e
)
251 GLC_UserInput
userInput(e
->x(), e
->y());
253 if (not m_MoverController
.hasActiveMover()) {
256 m_MoverController
.move(userInput
);
257 m_GlView
.setDistMinAndMax(m_World
.boundingBox());
261 void ModelViewGadgetWidget::mouseReleaseEvent(QMouseEvent
*)
263 if (not m_MoverController
.hasActiveMover()) {
266 m_MoverController
.setNoMover();
267 m_MotionTimer
.start();
271 void ModelViewGadgetWidget::keyPressEvent(QKeyEvent
*e
) // switch between camera
273 if (e
->key() == Qt::Key_1
) {
274 m_GlView
.cameraHandle()->setIsoView();
277 if (e
->key() == Qt::Key_2
) {
278 m_GlView
.cameraHandle()->setFrontView();
281 if (e
->key() == Qt::Key_3
) {
282 m_GlView
.cameraHandle()->setIsoView();
283 m_GlView
.cameraHandle()->rotateAroundTarget(glc::Z_AXIS
, glc::toRadian(90));
286 if (e
->key() == Qt::Key_4
) {
287 m_GlView
.cameraHandle()->setLeftView();
290 if (e
->key() == Qt::Key_5
) {
291 m_GlView
.cameraHandle()->setTopView();
292 m_GlView
.cameraHandle()->rotateAroundTarget(glc::Z_AXIS
, glc::toRadian(180));
295 if (e
->key() == Qt::Key_6
) {
296 m_GlView
.cameraHandle()->setRightView();;
299 if (e
->key() == Qt::Key_7
) {
300 m_GlView
.cameraHandle()->setIsoView();
301 m_GlView
.cameraHandle()->rotateAroundTarget(glc::Z_AXIS
, glc::toRadian(-90));
304 if (e
->key() == Qt::Key_8
) {
305 m_GlView
.cameraHandle()->setRearView();;
308 if (e
->key() == Qt::Key_9
) {
309 m_GlView
.cameraHandle()->setIsoView();
310 m_GlView
.cameraHandle()->rotateAroundTarget(glc::Z_AXIS
, glc::toRadian(180));
313 if (e
->key() == Qt::Key_0
) {
314 m_GlView
.cameraHandle()->setBottomView();
315 m_GlView
.cameraHandle()->rotateAroundTarget(glc::Z_AXIS
, glc::toRadian(180));
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
335 // create and gives the product of 2 4x4 matrices to get the rotation of the 3D model's matrix
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
));
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();