PeriDyno 1.0.0
Loading...
Searching...
No Matches
POpenGLWidget.cpp
Go to the documentation of this file.
1#include <glad/glad.h>
2
3#include "POpenGLWidget.h"
4#include "PSimulationThread.h"
5
6#include <SceneGraph.h>
7#include <OrbitCamera.h>
8
9//Qt
10#include <QMouseEvent>
11#include <QGuiApplication>
12#include <QScreen>
13
14#include "QtImGui.h"
15#include <ImWidget.h>
16
17#include "SceneGraphFactory.h"
18
19#include <GLRenderEngine.h>
20#include "QtApp.h"
21#include "ImGuizmo.h"
22
23#include <map>
24
25//stb
26#define STB_IMAGE_WRITE_IMPLEMENTATION
27#include <stb/stb_image_write.h>
28
29namespace dyno
30{
31 std::map<int, PKeyboardType> KeyMap =
32 {
33 {Qt::Key_unknown, PKEY_UNKNOWN},
34 {Qt::Key_Space, PKEY_SPACE},
35 {Qt::Key_Apostrophe, PKEY_APOSTROPHE},
36 {Qt::Key_Comma, PKEY_COMMA},
37 {Qt::Key_Minus, PKEY_MINUS},
38 {Qt::Key_Period, PKEY_PERIOD},
39 {Qt::Key_Slash, PKEY_SLASH},
40 {Qt::Key_0, PKEY_0},
41 {Qt::Key_1, PKEY_1},
42 {Qt::Key_2, PKEY_2},
43 {Qt::Key_3, PKEY_3},
44 {Qt::Key_4, PKEY_4},
45 {Qt::Key_5, PKEY_5},
46 {Qt::Key_6, PKEY_6},
47 {Qt::Key_7, PKEY_7},
48 {Qt::Key_8, PKEY_8},
49 {Qt::Key_9, PKEY_9},
50 {Qt::Key_Semicolon, PKEY_SEMICOLON},
51 {Qt::Key_Equal, PKEY_EQUAL},
52 {Qt::Key_A, PKEY_A},
53 {Qt::Key_B, PKEY_B},
54 {Qt::Key_C, PKEY_C},
55 {Qt::Key_D, PKEY_D},
56 {Qt::Key_E, PKEY_E},
57 {Qt::Key_F, PKEY_F},
58 {Qt::Key_G, PKEY_G},
59 {Qt::Key_H, PKEY_H},
60 {Qt::Key_I, PKEY_I},
61 {Qt::Key_J, PKEY_J},
62 {Qt::Key_K, PKEY_K},
63 {Qt::Key_L, PKEY_L},
64 {Qt::Key_M, PKEY_M},
65 {Qt::Key_N, PKEY_N},
66 {Qt::Key_O, PKEY_O},
67 {Qt::Key_P, PKEY_P},
68 {Qt::Key_Q, PKEY_Q},
69 {Qt::Key_R, PKEY_R},
70 {Qt::Key_S, PKEY_S},
71 {Qt::Key_T, PKEY_T},
72 {Qt::Key_U, PKEY_U},
73 {Qt::Key_V, PKEY_V},
74 {Qt::Key_W, PKEY_W},
75 {Qt::Key_X, PKEY_X},
76 {Qt::Key_Y, PKEY_Y},
77 {Qt::Key_Z, PKEY_Z},
78 {Qt::Key_Backslash, PKEY_BACKSLASH},
79 {Qt::Key_Escape, PKEY_ESCAPE},
80 {Qt::Key_Enter, PKEY_ENTER},
81 {Qt::Key_Tab, PKEY_TAB},
82 {Qt::Key_Backspace, PKEY_BACKSPACE},
83 {Qt::Key_Insert, PKEY_INSERT},
84 {Qt::Key_Delete, PKEY_DELETE},
85 {Qt::Key_Right, PKEY_RIGHT},
86 {Qt::Key_Left, PKEY_LEFT},
87 {Qt::Key_Down, PKEY_DOWN},
88 {Qt::Key_Up, PKEY_UP},
89 {Qt::Key_PageUp, PKEY_PAGE_UP},
90 {Qt::Key_PageDown, PKEY_PAGE_DOWN},
91 {Qt::Key_Home, PKEY_HOME},
92 {Qt::Key_End, PKEY_END},
93 {Qt::Key_CapsLock, PKEY_CAPS_LOCK},
94 {Qt::Key_ScrollLock, PKEY_SCROLL_LOCK},
95 {Qt::Key_NumLock, PKEY_NUM_LOCK},
96 {Qt::Key_Pause, PKEY_PAUSE},
97 {Qt::Key_F1, PKEY_F1},
98 {Qt::Key_F2, PKEY_F2},
99 {Qt::Key_F3, PKEY_F3},
100 {Qt::Key_F4, PKEY_F4},
101 {Qt::Key_F5, PKEY_F5},
102 {Qt::Key_F6, PKEY_F6},
103 {Qt::Key_F7, PKEY_F7},
104 {Qt::Key_F8, PKEY_F8},
105 {Qt::Key_F9, PKEY_F9},
106 {Qt::Key_F10, PKEY_F10},
107 {Qt::Key_F11, PKEY_F11},
108 {Qt::Key_F12, PKEY_F12},
109 {Qt::Key_F13, PKEY_F13},
110 {Qt::Key_F14, PKEY_F14},
111 {Qt::Key_F15, PKEY_F15},
112 {Qt::Key_F16, PKEY_F16},
113 {Qt::Key_F17, PKEY_F17},
114 {Qt::Key_F18, PKEY_F18},
115 {Qt::Key_F19, PKEY_F19},
116 {Qt::Key_F20, PKEY_F20},
117 {Qt::Key_F21, PKEY_F21},
118 {Qt::Key_F22, PKEY_F22},
119 {Qt::Key_F23, PKEY_F23},
120 {Qt::Key_F24, PKEY_F24},
121 {Qt::Key_F25, PKEY_F25}
122 };
123
125 : RenderWindow()
126 , QOpenGLWidget(parent)
127 {
128 QSurfaceFormat format;
129 format.setDepthBufferSize(24);
130 format.setMajorVersion(4);
131 format.setMinorVersion(6);
132 format.setSamples(4);
133 format.setSwapInterval(1);
134 format.setProfile(QSurfaceFormat::CoreProfile);
135 setFormat(format);
136
137 // Update at 60 fps
138 QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
139 timer.start(16);
140
141 setFocusPolicy(Qt::StrongFocus);
142
143 this->setRenderEngine(std::make_shared<GLRenderEngine>());
144 }
145
147 {
148 timer.stop();
149 //delete mRenderEngine;
150
151 makeCurrent();
152 this->getRenderEngine()->terminate();
153 doneCurrent();
154 }
155
157 {
158 if (!gladLoadGL()) {
159 //SPDLOG_CRITICAL("Failed to load GLAD!");
160 exit(-1);
161 }
162
163 initializeOpenGLFunctions();
165
166 // initialize render engine
167 if (this->getRenderEngine() == 0) {
168 this->setRenderEngine(std::make_shared<GLRenderEngine>());
169 }
170
171 this->getRenderEngine()->initialize();
172
173 // Get Context scale
174 float scale = QGuiApplication::primaryScreen()->logicalDotsPerInchX() / 96.0;
175 mImWindow.initialize(scale);
176
177 auto scn = SceneGraphFactory::instance()->active();
178
179 if (scn != nullptr)
180 {
181 scn->reset();
182 scn->updateGraphicsContext();
183 }
184 }
185
187 {
188 //QtImGui
190
191 // update rendering params
192 mRenderParams.width = mCamera->viewportWidth();
193 mRenderParams.height = mCamera->viewportHeight();
194 mRenderParams.transforms.model = glm::mat4(1); // TODO: world transform?
195 mRenderParams.transforms.view = mCamera->getViewMat();
196 mRenderParams.transforms.proj = mCamera->getProjMat();
197 mRenderParams.unitScale = mCamera->unitScale();
198
199 // Draw scene
201
202 // Draw ImGui
203 if (showImGUI())
204 mImWindow.draw(this);
205 // Draw widgets
206// // TODO: maybe move into mImWindow...
207// for (auto widget : mWidgets)
208// {
209// widget->update();
210// widget->paint();
211// }
212
213 ImGui::Render();
214 // Do QtImgui Render After Glfw Render
216 }
217
218 void POpenGLWidget::resizeGL(int w, int h)
219 {
220 qreal ratio = devicePixelRatio();
221
222 this->setWindowSize(floor(w * ratio), floor(h * ratio));
223 }
224
225 PButtonType mappingMouseButton(QMouseEvent* event)
226 {
227 if (event->buttons().testFlag(Qt::LeftButton))
228 {
230 }
231 else if (event->buttons().testFlag(Qt::MiddleButton))
232 {
234 }
235 else if (event->buttons().testFlag(Qt::RightButton))
236 {
238 }
239 }
240
241 PModifierBits mappingModifierBits(Qt::KeyboardModifiers mods)
242 {
243 if (mods == Qt::ControlModifier)
244 {
246 }
247 else if (mods == Qt::ShiftModifier)
248 {
250 }
251 else if (mods == Qt::AltModifier)
252 {
254 }
255 else
257 }
258
259 void POpenGLWidget::mousePressEvent(QMouseEvent *event)
260 {
261
263 mCursorX = event->x();
264 mCursorY = event->y();
265
266 auto camera = this->getCamera();
267 camera->registerPoint(event->x(), event->y());
268
269 //Primitive selection
271 {
272 PMouseEvent mouseEvent;
273 mouseEvent.ray = camera->castRayInWorldSpace((float)event->x(), (float)event->y());
274 mouseEvent.buttonType = mappingMouseButton(event);
276 mouseEvent.mods = mappingModifierBits(event->modifiers());
277 mouseEvent.camera = camera;
278 mouseEvent.x = (float)event->x();
279 mouseEvent.y = (float)event->y();
280
281 auto activeScene = SceneGraphFactory::instance()->active();
282
283 if (activeScene->getWorkMode() == SceneGraph::EDIT_MODE)
284 {
285 activeScene->onMouseEvent(mouseEvent, this->getCurrentSelectedNode());
286 }
287 else
288 activeScene->onMouseEvent(mouseEvent);
289
290 mImWindow.mousePressEvent(mouseEvent);
291 }
292
293 if (event->button() == Qt::RightButton)
294 {
295 mtempCursorX = event->x();
296 }
297
299 }
300
301 void POpenGLWidget::mouseReleaseEvent(QMouseEvent *event)
302 {
303 // Object selection
305 {
306 if ((event->modifiers() == 0 || event->modifiers() == Qt::ShiftModifier)
307 && event->button() == Qt::LeftButton
309 && !ImGui::GetIO().WantCaptureMouse)
310 {
311 int x = event->x();
312 int y = event->y();
313
314 int w = std::abs(mCursorX - x);
315 int h = std::abs(mCursorY - y);
316 x = std::min(mCursorX, x);
317 y = std::min(mCursorY, y);
318 // flip y
319 y = this->height() - y - 1;
320
321 makeCurrent();
322 const auto& selection = this->select(x, y, w, h);
323 doneCurrent();
324 }
325 }
326
327 //Primitive selection
329 {
330 auto camera = this->getCamera();
331
333
334 PMouseEvent mouseEvent;
335 mouseEvent.ray = camera->castRayInWorldSpace((float)event->x(), (float)event->y());
336 mouseEvent.buttonType = mappingMouseButton(event);
338 mouseEvent.mods = mappingModifierBits(event->modifiers());
339 mouseEvent.camera = camera;
340 mouseEvent.x = (float)event->x();
341 mouseEvent.y = (float)event->y();
342
343
344 auto activeScene = SceneGraphFactory::instance()->active();
345
346 activeScene->onMouseEvent(mouseEvent, this->getCurrentSelectedNode());
347
348 mImWindow.mouseReleaseEvent(mouseEvent);
349 }
350
352 }
353
354 void POpenGLWidget::mouseMoveEvent(QMouseEvent *event)
355 {
356 auto camera = this->getCamera();
357
358 if (event->buttons().testFlag(Qt::LeftButton) &&
360 event->modifiers() == Qt::AltModifier &&
361 !mImWindow.cameraLocked())
362 {
363 camera->rotateToPoint(event->x(), event->y());
364 }
365 else if (event->buttons().testFlag(Qt::RightButton) &&
367 event->modifiers() == Qt::AltModifier &&
368 !mImWindow.cameraLocked())
369 {
370 camera->zoom(-0.005*float(event->x()-mtempCursorX));
371 mtempCursorX = event->x();
372 }
373 else if (event->buttons().testFlag(Qt::MiddleButton) &&
375 event->modifiers() == Qt::AltModifier &&
376 !mImWindow.cameraLocked())
377 {
378 camera->translateToPoint(event->x(), event->y());
379 }
380
382 {
383 PMouseEvent mouseEvent;
384 mouseEvent.ray = camera->castRayInWorldSpace((float)event->x(), (float)event->y());
385 mouseEvent.buttonType = mappingMouseButton(event);
387 mouseEvent.mods = mappingModifierBits(event->modifiers());
388 mouseEvent.camera = camera;
389 mouseEvent.x = (float)event->x();
390 mouseEvent.y = (float)event->y();
391
392 auto activeScene = SceneGraphFactory::instance()->active();
393
394 activeScene->onMouseEvent(mouseEvent, this->getCurrentSelectedNode());
395
396 //To draw a selected region
397 mImWindow.mouseMoveEvent(mouseEvent);
398 }
399
401 }
402
403 void POpenGLWidget::wheelEvent(QWheelEvent *event)
404 {
405 if(!mImWindow.cameraLocked())
406 this->getCamera()->zoom(-0.001*event->angleDelta().x());
407
408 update();
409 }
410
411 void POpenGLWidget::keyPressEvent(QKeyEvent* event)
412 {
413 auto activeScene = SceneGraphFactory::instance()->active();
414
415 PKeyboardEvent keyEvent;
416 keyEvent.key = KeyMap[event->key()];
417 keyEvent.action = AT_PRESS;
418 keyEvent.mods = mappingModifierBits(event->modifiers());
419
420 activeScene->onKeyboardEvent(keyEvent);
421
422 switch (event->key())
423 {
424 case Qt::Key_F1:
425 this->toggleImGUI();
426 break;
427 default:
428 break;
429 }
430 }
431
432 void POpenGLWidget::keyReleaseEvent(QKeyEvent* event)
433 {
434 auto activeScene = SceneGraphFactory::instance()->active();
435
436 PKeyboardEvent keyEvent;
437 keyEvent.key = KeyMap[event->key()];
438 keyEvent.action = AT_RELEASE;
439 keyEvent.mods = mappingModifierBits(event->modifiers());
440
441 activeScene->onKeyboardEvent(keyEvent);
442 }
443
445 {
446 if (s.items.empty())
447 return;
448
449 //Disable node selection as simulation is started.
450 if(PSimulationThread::instance()->isPaused())
451 emit this->nodeSelected(s.items[0].node);
452 }
453
455 {
456 makeCurrent();
457
459
460 SceneGraphFactory::instance()->active()->updateGraphicsContext();
461
463
464 update();
465
466 doneCurrent();
467 }
468
470 {
471 makeCurrent();
472
474
475 node->graphicsPipeline()->forceUpdate();
476
478
479 update();
480
481 doneCurrent();
482 }
483
485 {
486 if (!this->isScreenRecordingOn())
487 return;
488
489 saveScreen(frame);
490 }
491
492 void POpenGLWidget::onSaveScreen(const std::string& filename)
493 {
494 QImage image = QOpenGLWidget::grabFramebuffer();
495
496 image.save(filename.c_str());
497 }
498
499}
std::shared_ptr< GraphicsPipeline > graphicsPipeline()
Definition Node.cpp:320
void nodeSelected(std::shared_ptr< Node > node)
void onSaveScreen(const std::string &filename) override
void updateGraphicsContext(Node *node)
void updateOneFrame(int frame)
void mouseReleaseEvent(QMouseEvent *event) override
void keyReleaseEvent(QKeyEvent *event) override
void initializeGL() override
void mousePressEvent(QMouseEvent *event) override
void onSelected(const Selection &s) override
void mouseMoveEvent(QMouseEvent *event) override
void keyPressEvent(QKeyEvent *event) override
void resizeGL(int w, int h) override
void paintGL() override
POpenGLWidget(QWidget *parent=nullptr)
QButtonState mButtonState
void wheelEvent(QWheelEvent *event) override
static PSimulationThread * instance()
virtual std::shared_ptr< Camera > getCamera()
void saveScreen(unsigned int frame)
virtual std::shared_ptr< RenderEngine > getRenderEngine()
SelectionMode getSelectionMode()
std::shared_ptr< Camera > mCamera
bool & isScreenRecordingOn()
RenderParams mRenderParams
std::shared_ptr< RenderEngine > mRenderEngine
virtual const Selection & select(int x, int y, int w, int h)
virtual void setRenderEngine(std::shared_ptr< RenderEngine > engine)
virtual std::shared_ptr< Node > getCurrentSelectedNode()
virtual void setWindowSize(int w, int h)
static SceneGraphFactory * instance()
std::shared_ptr< SceneGraph > active()
bool IsUsing()
Definition ImGuizmo.cpp:936
void render(RenderRef ref)
Definition QtImGui.cpp:180
void newFrame(RenderRef ref)
Definition QtImGui.cpp:171
RenderRef initialize(QWindow *window, bool defaultRender)
Definition QtImGui.cpp:157
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
PButtonType mappingMouseButton(QMouseEvent *event)
PModifierBits
@ MB_CONTROL
@ MB_NO_MODIFIER
@ MB_SHIFT
PModifierBits mappingModifierBits(Qt::KeyboardModifiers mods)
@ AT_RELEASE
Definition InputModule.h:35
@ AT_PRESS
Definition InputModule.h:36
@ AT_REPEAT
Definition InputModule.h:37
@ PKEY_P
Definition InputModule.h:76
@ PKEY_S
Definition InputModule.h:79
@ PKEY_LEFT
@ PKEY_APOSTROPHE
Definition InputModule.h:44
@ PKEY_F4
@ PKEY_F6
@ PKEY_A
Definition InputModule.h:61
@ PKEY_F25
@ PKEY_T
Definition InputModule.h:80
@ PKEY_F2
@ PKEY_NUM_LOCK
@ PKEY_4
Definition InputModule.h:53
@ PKEY_H
Definition InputModule.h:68
@ PKEY_F5
@ PKEY_F8
@ PKEY_O
Definition InputModule.h:75
@ PKEY_1
Definition InputModule.h:50
@ PKEY_Q
Definition InputModule.h:77
@ PKEY_EQUAL
Definition InputModule.h:60
@ PKEY_F20
@ PKEY_7
Definition InputModule.h:56
@ PKEY_F11
@ PKEY_F7
@ PKEY_SPACE
Definition InputModule.h:43
@ PKEY_F21
@ PKEY_BACKSPACE
Definition InputModule.h:96
@ PKEY_Y
Definition InputModule.h:85
@ PKEY_F17
@ PKEY_D
Definition InputModule.h:64
@ PKEY_J
Definition InputModule.h:70
@ PKEY_F15
@ PKEY_R
Definition InputModule.h:78
@ PKEY_PERIOD
Definition InputModule.h:47
@ PKEY_C
Definition InputModule.h:63
@ PKEY_F22
@ PKEY_5
Definition InputModule.h:54
@ PKEY_SLASH
Definition InputModule.h:48
@ PKEY_3
Definition InputModule.h:52
@ PKEY_N
Definition InputModule.h:74
@ PKEY_PAUSE
@ PKEY_F23
@ PKEY_F24
@ PKEY_RIGHT
Definition InputModule.h:99
@ PKEY_SCROLL_LOCK
@ PKEY_F1
@ PKEY_I
Definition InputModule.h:69
@ PKEY_F18
@ PKEY_F10
@ PKEY_V
Definition InputModule.h:82
@ PKEY_F
Definition InputModule.h:66
@ PKEY_COMMA
Definition InputModule.h:45
@ PKEY_K
Definition InputModule.h:71
@ PKEY_DOWN
@ PKEY_SEMICOLON
Definition InputModule.h:59
@ PKEY_F16
@ PKEY_F14
@ PKEY_F9
@ PKEY_B
Definition InputModule.h:62
@ PKEY_PAGE_UP
@ PKEY_END
@ PKEY_W
Definition InputModule.h:83
@ PKEY_MINUS
Definition InputModule.h:46
@ PKEY_G
Definition InputModule.h:67
@ PKEY_INSERT
Definition InputModule.h:97
@ PKEY_BACKSLASH
Definition InputModule.h:88
@ PKEY_UNKNOWN
Definition InputModule.h:42
@ PKEY_8
Definition InputModule.h:57
@ PKEY_2
Definition InputModule.h:51
@ PKEY_6
Definition InputModule.h:55
@ PKEY_E
Definition InputModule.h:65
@ PKEY_F3
@ PKEY_ESCAPE
Definition InputModule.h:93
@ PKEY_UP
@ PKEY_F19
@ PKEY_F12
@ PKEY_HOME
@ PKEY_0
Definition InputModule.h:49
@ PKEY_Z
Definition InputModule.h:86
@ PKEY_U
Definition InputModule.h:81
@ PKEY_ENTER
Definition InputModule.h:94
@ PKEY_9
Definition InputModule.h:58
@ PKEY_F13
@ PKEY_X
Definition InputModule.h:84
@ PKEY_CAPS_LOCK
@ PKEY_M
Definition InputModule.h:73
@ PKEY_TAB
Definition InputModule.h:95
@ PKEY_DELETE
Definition InputModule.h:98
@ PKEY_L
Definition InputModule.h:72
@ PKEY_PAGE_DOWN
std::map< int, PKeyboardType > KeyMap
@ QBUTTON_DOWN
@ QBUTTON_UP
PButtonType
Definition InputModule.h:25
@ BT_MIDDLE
Definition InputModule.h:29
@ BT_LEFT
Definition InputModule.h:27
@ BT_RIGHT
Definition InputModule.h:28
PKeyboardType key
PModifierBits mods
TRay3D< float > ray
PButtonType buttonType
std::shared_ptr< Camera > camera
PModifierBits mods
PActionType actionType
std::vector< Item > items