Apollo 11.0
自动驾驶开放平台
scene_viewer.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <QtCore/QTimer>
20#include <QtGui/QWheelEvent>
21#include <QtWidgets/QMessageBox>
22
24
27 QList<RenderableObject *> objGroupList_;
28
31 while (!objGroupList_.isEmpty()) {
32 delete objGroupList_.takeFirst();
33 }
34
35 objGroupList_.clear();
36 }
37
38 bool isEmpty(void) const { return objGroupList_.isEmpty(); }
39
40 bool isEnabled(void) const { return isEnabled_; }
41
42 void append(RenderableObject *obj) { objGroupList_.append(obj); }
43 RenderableObject *takeFirst(void) { return objGroupList_.takeFirst(); }
44 RenderableObject *takeLast(void) { return objGroupList_.takeLast(); }
45};
46
48 : QOpenGLWidget(parent),
49 QOpenGLFunctions(),
50 is_init_(false),
51 right_key_is_moved_(false),
52 sensitivity_(0.08f),
53 refreshTimer_(nullptr),
54 left_key_last_pos_(),
55 right_key_last_y_(0),
56 camera_dialog_(nullptr),
57 current_cameraPtr_(nullptr),
58 free_camera_(),
59 target_camera_(),
60 managed_shader_prog_(),
61 tmp_renderable_obj_list_(),
62 permanent_renderable_obj_list_() {
63 current_cameraPtr_ = &target_camera_;
64}
65
67 if (is_init_) {
68 is_init_ = false;
69
70 refreshTimer_->stop();
71 delete refreshTimer_;
72
73 makeCurrent();
74
75 auto iter = managed_shader_prog_.begin();
76 for (; iter != managed_shader_prog_.end(); ++iter) {
77 iter->second->destroyed();
78 iter->second.reset();
79 }
80
81 managed_shader_prog_.clear();
82
83 for (auto &iter : tmp_renderable_obj_list_) {
84 delete iter.second;
85 }
86
87 tmp_renderable_obj_list_.clear();
88
89 while (!permanent_renderable_obj_list_.isEmpty()) {
90 delete permanent_renderable_obj_list_.takeFirst();
91 }
92
93 doneCurrent();
94 }
95}
96
97void SceneViewer::setTempObjGroupEnabled(const std::string &tmpObjGroupName,
98 bool b) {
99 auto iter = tmp_renderable_obj_list_.find(tmpObjGroupName);
100 if (iter != tmp_renderable_obj_list_.cend()) {
101 iter->second->isEnabled_ = b;
102 }
103}
104
105bool SceneViewer::AddTempRenderableObj(const std::string &tmpObjGroupName,
106 RenderableObject *renderObj) {
107 bool ret = false;
108 if (renderObj && renderObj->haveShaderProgram() && is_init_) {
109 auto iter = tmp_renderable_obj_list_.find(tmpObjGroupName);
110 if (iter == tmp_renderable_obj_list_.cend()) {
112 if (objGroup) {
113 objGroup->append(renderObj);
114 tmp_renderable_obj_list_.insert(
115 std::make_pair(tmpObjGroupName, objGroup));
116 ret = true;
117 }
118 } else {
119 iter->second->objGroupList_.append(renderObj);
120 ret = true;
121 }
122 }
123
124 return ret;
125}
126
128 const std::string &shaderProgName,
129 const std::shared_ptr<QOpenGLShaderProgram> &newShaderProg) {
130 if (newShaderProg == nullptr) {
131 return;
132 }
133
134 auto iter = managed_shader_prog_.find(shaderProgName);
135 if (iter != managed_shader_prog_.end()) {
136 iter->second.reset();
137 }
138
139 QMatrix4x4 mvp = current_cameraPtr_->projection_matrix() *
140 current_cameraPtr_->model_view_matrix();
141
142 newShaderProg->bind();
143 newShaderProg->setUniformValue("mvp", mvp);
144 newShaderProg->release();
145
146 managed_shader_prog_[shaderProgName] = newShaderProg;
147}
148
150 initializeOpenGLFunctions();
151
152 glPointSize(1.0f);
153 glEnable(GL_PROGRAM_POINT_SIZE);
154 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
155
156 refreshTimer_ = new QTimer(this);
157 if (!refreshTimer_) {
158 return;
159 }
160
161 refreshTimer_->setObjectName(tr("_refreshTimer"));
162 refreshTimer_->setInterval(40);
163 refreshTimer_->start();
164 connect(refreshTimer_, SIGNAL(timeout()), this, SLOT(repaint()));
165
166 free_camera_.SetUpProjection(45.0f, GLfloat(width()), GLfloat(height()));
167 target_camera_.SetUpProjection(45.0f, GLfloat(width()), GLfloat(height()));
169
170 is_init_ = true;
171}
172
173void SceneViewer::resizeGL(int width, int height) {
174 glViewport(0, 0, (GLsizei)width, (GLsizei)height);
175
176 if (is_init_) {
177 free_camera_.set_near_plane_width(GLfloat(width));
178 free_camera_.set_near_plane_height(GLfloat(height));
179 free_camera_.UpdateProjection();
180
181 target_camera_.set_near_plane_width(GLfloat(width));
182 target_camera_.set_near_plane_height(GLfloat(height));
183 target_camera_.UpdateProjection();
184
185 QMatrix4x4 mvp = current_cameraPtr_->projection_matrix() *
186 current_cameraPtr_->model_view_matrix();
187
188 UpdateAllShaderProgMVP(mvp);
189 }
190}
191
193 if (is_init_) {
194 for (RenderableObject *item : permanent_renderable_obj_list_) {
195 if (item->Init()) {
196 item->Render();
197 }
198 }
199
200 for (auto &iter : tmp_renderable_obj_list_) {
201 if (!iter.second->isEmpty()) {
202 RenderableObject *lastItem = nullptr;
203
204 if (iter.second->isEnabled()) {
205 lastItem = iter.second->takeLast();
206 if (lastItem->Init()) {
207 lastItem->Render();
208 }
209 }
210
211 while (!iter.second->isEmpty()) {
212 delete iter.second->takeFirst();
213 }
214
215 if (lastItem) {
216 iter.second->append(lastItem);
217 }
218 }
219 }
220 }
221}
222
224 if (index < TARGET || index > FREE) {
225 return;
226 }
227 if (index == FREE) {
228 current_cameraPtr_ = &free_camera_;
229 } else {
230 current_cameraPtr_ = &target_camera_;
231 }
233}
234
236 free_camera_.set_position(0.0f, 48.0f, -48.0f);
237 free_camera_.SetAttitude(0.0f, 45.0f, 0.0f);
238
239 target_camera_.set_position(-21.0f, 21.0f, 0.0f);
240 target_camera_.Rotate(-45.0f, -90.0f, 0.0f);
241 target_camera_.set_target_pos(0.0f, 0.0f, 0.0f);
242
243 emit CameraPosChanged(current_cameraPtr_->position());
244 emit CameraAttitudeChanged(current_cameraPtr_->attitude());
245
246 UpdateCameraWorld();
247}
248
250 free_camera_.set_x(static_cast<float>(x));
251 target_camera_.set_x(static_cast<float>(x));
252 UpdateCameraWorld();
253}
254
256 free_camera_.set_y(static_cast<float>(y));
257 target_camera_.set_y(static_cast<float>(y));
258 UpdateCameraWorld();
259}
260
262 free_camera_.set_z(static_cast<float>(z));
263 target_camera_.set_y(static_cast<float>(z));
264 UpdateCameraWorld();
265}
266
267void SceneViewer::UpdateCameraYaw(double yawInDegrees) {
268 if (yawInDegrees > 360.0) {
269 yawInDegrees -= 360.0;
270 }
271 if (yawInDegrees < -360.0) {
272 yawInDegrees += 360.0;
273 }
274
275 free_camera_.set_yaw(static_cast<float>(yawInDegrees));
276 target_camera_.set_yaw(static_cast<float>(yawInDegrees));
277 UpdateCameraWorld();
278}
279
280void SceneViewer::UpdateCameraPitch(double pitchInDegrees) {
281 if (pitchInDegrees > 90.0) {
282 pitchInDegrees = 90.0;
283 }
284 if (pitchInDegrees < -90.0) {
285 pitchInDegrees = -90.0;
286 }
287
288 free_camera_.set_pitch(static_cast<float>(pitchInDegrees));
289 target_camera_.set_pitch(static_cast<float>(pitchInDegrees));
290 UpdateCameraWorld();
291}
292void SceneViewer::UpdateCameraRoll(double rollInDegrees) {
293 if (rollInDegrees > 360.0) {
294 rollInDegrees -= 360.0;
295 }
296 if (rollInDegrees < -360.0) {
297 rollInDegrees += 360.0;
298 }
299
300 free_camera_.set_roll(static_cast<float>(rollInDegrees));
301 free_camera_.set_roll(static_cast<float>(rollInDegrees));
302 UpdateCameraWorld();
303}
304
305void SceneViewer::UpdateCameraWorld(void) {
306 free_camera_.UpdateWorld();
307 target_camera_.UpdateWorld();
308
309 QMatrix4x4 mvp = current_cameraPtr_->projection_matrix() *
310 current_cameraPtr_->model_view_matrix();
311
312 UpdateAllShaderProgMVP(mvp);
313
314 update();
315}
316
317void SceneViewer::UpdateAllShaderProgMVP(const QMatrix4x4 &mvp) {
318 for (auto iter = managed_shader_prog_.begin();
319 iter != managed_shader_prog_.end(); ++iter) {
320 iter->second->bind();
321 iter->second->setUniformValue("mvp", mvp);
322 iter->second->release();
323 }
324}
325
326void SceneViewer::enterEvent(QEvent *event) {
327 setCursor(Qt::SizeAllCursor);
328 QOpenGLWidget::enterEvent(event);
329}
330
331void SceneViewer::leaveEvent(QEvent *event) {
332 unsetCursor();
333 QOpenGLWidget::leaveEvent(event);
334}
335
336void SceneViewer::mousePressEvent(QMouseEvent *event) {
337 if (event->button() == Qt::LeftButton) {
338 left_key_last_pos_ = QCursor::pos();
339 } else if (event->button() == Qt::RightButton) {
340 right_key_is_moved_ = false;
341 right_key_last_y_ = static_cast<float>(QCursor::pos().y());
342 }
343
344 QOpenGLWidget::mousePressEvent(event);
345}
346
347void SceneViewer::mouseMoveEvent(QMouseEvent *mouseEvent) {
348 if (mouseEvent->buttons() == Qt::LeftButton) {
349 QPoint tmp = QCursor::pos();
350 QPoint dd = tmp - left_key_last_pos_;
351 left_key_last_pos_ = tmp;
352
353 float x = static_cast<float>(dd.x()) * sensitivity();
354 float y = static_cast<float>(dd.y()) * sensitivity();
355
356 if (IsFreeCamera()) {
357 free_camera_.Starfe(-x);
358 free_camera_.Lift(y);
359
360 emit CameraPosChanged(free_camera_.position());
361 } else {
362 x = target_camera_.yaw() - x;
363 y = target_camera_.pitch() - y;
364
365 if (x > 360.0f) {
366 x -= 360.0f;
367 }
368 if (x < -360.0f) {
369 x += 360.0f;
370 }
371
372 if (y > 90.0f) {
373 y = 90.0f;
374 }
375 if (y < -90.0f) {
376 y = 90.0f;
377 }
378
379 target_camera_.set_yaw(x);
380 target_camera_.set_pitch(y);
381
382 emit CameraAttitudeChanged(target_camera_.attitude());
383 }
384
385 goto _label1;
386 } else if (mouseEvent->buttons() == Qt::RightButton) {
387 right_key_is_moved_ = true;
388 if (IsFreeCamera()) {
389 {
390 float tmp = static_cast<float>(QCursor::pos().y());
391 float dd = right_key_last_y_ - tmp;
392 right_key_last_y_ = tmp;
393
394 float z = dd * sensitivity();
395
396 free_camera_.Walk(z);
397
398 emit CameraPosChanged(free_camera_.position());
399 }
400
401 _label1:
402 UpdateCameraWorld();
403 update();
404 }
405 }
406 QOpenGLWidget::mousePressEvent(mouseEvent);
407}
408
409void SceneViewer::wheelEvent(QWheelEvent *event) {
410 float delta = static_cast<float>(event->angleDelta().y());
411 delta *= sensitivity();
412
413 target_camera_.set_distance(target_camera_.distance() + delta);
414
415 delta += free_camera_.pitch();
416 if (delta > 90.0f) {
417 delta = 90.0f;
418 }
419 if (delta < -90.0f) {
420 delta = -90.0f;
421 }
422 free_camera_.set_pitch(delta);
423
424 if (IsFreeCamera()) {
425 emit CameraAttitudeChanged(free_camera_.attitude());
426 } else {
427 emit CameraPosChanged(target_camera_.position());
428 }
429 UpdateCameraWorld();
430 update();
431
432 QOpenGLWidget::wheelEvent(event);
433}
434
435void SceneViewer::mouseReleaseEvent(QMouseEvent *event) {
436 if (!right_key_is_moved_ && event->button() == Qt::RightButton) {
437 if (camera_dialog_ == nullptr) {
438 camera_dialog_ = new SceneCameraDialog(this);
439 if (!camera_dialog_) {
440 QMessageBox::warning(this, tr("Error"),
441 tr("No Enough for creating Camera Dialog!!!"),
442 QMessageBox::Ok);
443 goto retLabel;
444 } else {
445 connect(camera_dialog_, SIGNAL(resetcamera()), this,
446 SLOT(ResetCameraPosAttitude()));
447 connect(camera_dialog_, SIGNAL(xValueChanged(double)), this,
448 SLOT(UpdateCameraX(double)));
449 connect(camera_dialog_, SIGNAL(yValueChanged(double)), this,
450 SLOT(UpdateCameraY(double)));
451 connect(camera_dialog_, SIGNAL(zValueChanged(double)), this,
452 SLOT(UpdateCameraZ(double)));
453 connect(camera_dialog_, SIGNAL(yawValueChanged(double)), this,
454 SLOT(UpdateCameraYaw(double)));
455 connect(camera_dialog_, SIGNAL(pitchValueChanged(double)), this,
456 SLOT(UpdateCameraPitch(double)));
457 connect(camera_dialog_, SIGNAL(rollValueChanged(double)), this,
458 SLOT(UpdateCameraRoll(double)));
459 connect(camera_dialog_, SIGNAL(cameraTypeChanged(int)), this,
460 SLOT(ChangeCameraType(int)));
461 connect(camera_dialog_, SIGNAL(sensitivityChanged(float)), this,
462 SLOT(set_sensitivity(float)));
463
464 connect(this, SIGNAL(CameraAttitudeChanged(QVector3D)), camera_dialog_,
465 SLOT(updateCameraAttitude(QVector3D)));
466 connect(this, SIGNAL(CameraPosChanged(QVector3D)), camera_dialog_,
467 SLOT(updateCameraPos(QVector3D)));
468 }
469 }
470 camera_dialog_->updateCameraPos(current_cameraPtr_->position());
471 camera_dialog_->updateCameraAttitude(current_cameraPtr_->attitude());
472
473 camera_dialog_->move(event->globalPos());
474 camera_dialog_->show();
475 }
476
477retLabel:
478 QOpenGLWidget::mouseReleaseEvent(event);
479}
void set_x(float x)
void set_near_plane_width(const float npWidth)
void SetUpProjection(float fovInDegrees, float nearPlaneWidth, float nearPlaneHeight, float near=0.1f, float far=1000.f)
void set_roll(float rInDegrees)
const QVector3D & position(void) const
void set_yaw(float yInDegrees)
void set_position(const QVector3D &pos)
const QMatrix4x4 & model_view_matrix(void) const
void UpdateProjection(void)
void set_pitch(float pInDegrees)
float pitch(void) const
void SetAttitude(float yawInDegrees, float pitchInDegrees, float rollInDegrees)
const QMatrix4x4 & projection_matrix(void) const
void set_y(float y)
void set_near_plane_height(const float npHeight)
const QVector3D & attitude(void) const
void set_z(float z)
float yaw(void) const
virtual void UpdateWorld(void)
void Starfe(const float dt)
Definition free_camera.h:34
void Lift(const float dt)
Definition free_camera.h:35
void Walk(const float dt)
Definition free_camera.h:33
bool Init(std::shared_ptr< QOpenGLShaderProgram > &shaderProgram=NullRenderableObj)
void Render(const QMatrix4x4 *mvp=nullptr)
bool haveShaderProgram(void)
void updateCameraPos(const QVector3D &)
void updateCameraAttitude(const QVector3D &)
bool IsFreeCamera(void) const
void resizeGL(int w, int h) override
void mouseMoveEvent(QMouseEvent *mouseEvent) override
void enterEvent(QEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
void leaveEvent(QEvent *event) override
void CameraAttitudeChanged(const QVector3D &attitude)
void mousePressEvent(QMouseEvent *mouseEvent) override
void ChangeCameraType(int index)
void UpdateCameraY(double Y)
void UpdateCameraRoll(double rollInDegrees)
void AddNewShaderProg(const std::string &shaderProgName, const std::shared_ptr< QOpenGLShaderProgram > &newShaderProg)
void initializeGL() override
void UpdateCameraPitch(double pitchInDegrees)
bool AddTempRenderableObj(const std::string &tmpObjGroupName, RenderableObject *renderObj)
void paintGL() override
void ResetCameraPosAttitude(void)
void set_sensitivity(float s)
float sensitivity(void) const
SceneViewer(QWidget *parent=nullptr)
void setTempObjGroupEnabled(const std::string &tmpObjGroupName, bool b)
void UpdateCameraYaw(double yawInDegrees)
void wheelEvent(QWheelEvent *event) override
void CameraPosChanged(const QVector3D &pos)
void UpdateCameraX(double x)
void UpdateCameraZ(double Z)
virtual void UpdateWorld()
float distance(void) const
void Rotate(float xRotateDegrees, float yRotateDegrees, float zRotateDegrees)
void set_distance(float distance)
void set_target_pos(float x, float y, float z)
RenderableObject * takeFirst(void)
void append(RenderableObject *obj)
RenderableObject * takeLast(void)
QList< RenderableObject * > objGroupList_