Tornado-Visualization/datenvisualisierung_sose2024/opengldisplaywidget.cpp

309 lines
9.7 KiB
C++
Raw Normal View History

2024-05-20 17:42:22 +00:00
#include "opengldisplaywidget.h"
#include <QMouseEvent>
#include <QKeyEvent>
#include <QOpenGLFunctions>
#include <iostream>
#include "math.h"
#include "cartesiangridtohorizontalslicefilter.h"
#include "horizontalslicetoimagemapper.h"
#include "horizontalslicerenderer.h"
#include "flowdatasource.h"
2024-06-19 15:01:53 +00:00
2024-07-05 11:00:39 +00:00
// Define grid size here
2024-06-15 18:50:23 +00:00
#define XValue 16
#define YValue 16
#define ZValue 16
2024-05-20 17:42:22 +00:00
OpenGLDisplayWidget::OpenGLDisplayWidget(QWidget *parent)
: QOpenGLWidget(parent),
distanceToCamera(-8.0)
{
setFocusPolicy(Qt::StrongFocus);
2024-06-19 15:01:53 +00:00
animate = false;
timey = new QTimer(this);
connect(timey, &QTimer::timeout, this, QOverload<>::of(&OpenGLDisplayWidget::animateVisual));
2024-05-20 17:42:22 +00:00
}
OpenGLDisplayWidget::~OpenGLDisplayWidget()
{
2024-07-05 11:00:39 +00:00
// Cleans up visualization pipeline
2024-05-20 17:42:22 +00:00
//delete bboxRenderer;
delete grid;
delete filter;
delete mapper;
delete renderer;
2024-06-11 11:02:20 +00:00
delete contourrenderer;
2024-07-05 11:00:39 +00:00
delete streamlinemapper;
delete streamlinerenderer;
2024-05-20 17:42:22 +00:00
// ....
}
QString OpenGLDisplayWidget::openGLString()
{
QString profileStr;
switch (format().profile())
{
case QSurfaceFormat::NoProfile:
profileStr = "no profile";
break;
case QSurfaceFormat::CompatibilityProfile:
profileStr = "compatibility profile";
break;
case QSurfaceFormat::CoreProfile:
profileStr = "core profile";
break;
}
return QString("%1.%2 (%3)").arg(format().majorVersion())
.arg(format().minorVersion()).arg(profileStr);
}
void OpenGLDisplayWidget::initializeGL()
{
// Query and display some information about the used OpenGL context.
std::cout << "Initializing OpenGLDisplayWidget with OpenGL version "
<< openGLString().toStdString() << ".\n" << std::flush;
// Set the backgound color of the OpenGL display enable the depth buffer.
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClearColor(0, 0, 0, 1);
f->glEnable(GL_DEPTH_TEST);
// Our own initialization of the visualization pipeline.
initVisualizationPipeline();
}
void OpenGLDisplayWidget::resizeGL(int w, int h)
{
// Calculate aspect ratio of the current viewport.
float aspectRatio = float(w) / std::max(1, h);
// Reset projection and set new perspective projection.
projectionMatrix.setToIdentity();
projectionMatrix.perspective(45.0, aspectRatio, 0.05, 25.0);
// Update model-view-projection matrix with new projection.
updateMVPMatrix();
}
void OpenGLDisplayWidget::paintGL()
{
// Clear color and depth buffer.
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2024-07-05 11:00:39 +00:00
// Calls renderer modules
2024-05-20 17:42:22 +00:00
//bboxRenderer->drawBoundingBox(mvpMatrix);
renderer->drawBoundingBox(mvpMatrix);
renderer->drawFrame(mvpMatrix);
renderer->drawImage(mvpMatrix);
2024-06-11 11:02:20 +00:00
contourrenderer->draw(mvpMatrix);
2024-07-05 11:00:39 +00:00
streamlinerenderer->draw(mvpMatrix);
2024-05-20 17:42:22 +00:00
// ....
}
void OpenGLDisplayWidget::mousePressEvent(QMouseEvent *e)
{
// Save the current position of the mouse pointer for subsequent use
// in mouseMoveEvent().
lastMousePosition = QVector2D(e->localPos());
}
void OpenGLDisplayWidget::mouseMoveEvent(QMouseEvent *e)
{
// If the user holds the left mouse button while moving the mouse, update
// the rotation angles that specify from which side the grid visualization
// is viewed.
if (e->buttons() & Qt::LeftButton)
{
// Vector that points from the last stored position of the mouse
// pointer to the current position.
QVector2D mousePosDifference = QVector2D(e->localPos()) - lastMousePosition;
// Update rotation angles in x and y direction. The factor "10" is an
// arbitrary scaling constant that controls the sensitivity of the
// mouse.
rotationAngles.setX(
fmod(rotationAngles.x() + mousePosDifference.x()/10.,
360.));
rotationAngles.setY(
fmod(rotationAngles.y() + mousePosDifference.y()/10.,
360.));
// Store current position of mouse pointer for next call to this method.
lastMousePosition = QVector2D(e->localPos());
// Update model-view-projection matrix with new rotation angles.
updateMVPMatrix();
// Redraw OpenGL.
update();
}
}
void OpenGLDisplayWidget::wheelEvent(QWheelEvent *e)
{
// Update distance of the camera to the rendered visualization. The factor
// "500" is arbitrary and controls that sensitivity of the mouse.
distanceToCamera += e->delta() / 500.;
// Update model-view-projection matrix with new distance to camera.
updateMVPMatrix();
// Redraw OpenGL.
update();
}
void OpenGLDisplayWidget::keyPressEvent(QKeyEvent *e)
{
2024-07-05 11:00:39 +00:00
// This function looks for key presses and then executes the corresponding command
// up and down move the slice up and down
// x,y,z and m activate various wind components or display the magnitude
// note that we only need to change the i in the Filter pointer, which is why
// this implementation should be fast
// Space starts an animation (implemented with a timer)
// R resets the time
// left and right enable the user to check specific times
2024-05-20 17:42:22 +00:00
if (e->key() == Qt::Key_Up)
{
2024-06-15 18:50:23 +00:00
if (renderer->z < ZValue -1) {
2024-05-20 17:42:22 +00:00
renderer->moveSlice(1);
filter->setSlice(renderer->z);
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue));
contourmapper->newZ(filter->passSlice(XValue,YValue), renderer->z);
2024-05-20 17:42:22 +00:00
}
}
else if (e->key() == Qt::Key_Down)
{
if (renderer->z > 0) {
renderer->moveSlice(-1);
filter->setSlice(renderer->z);
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue));
contourmapper->newZ(filter->passSlice(XValue,YValue), renderer->z);
2024-05-20 17:42:22 +00:00
}
} else if (e->key() == Qt::Key_X) {
mapper->setMagnitude(false);
2024-07-05 11:00:39 +00:00
contourmapper->setMagnitude(false);
2024-05-20 17:42:22 +00:00
filter->changeWindComponent(0);
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue));
contourmapper->newZ(filter->passSlice(XValue,YValue), renderer->z);
2024-05-20 17:42:22 +00:00
} else if (e->key() == Qt::Key_Y) {
mapper->setMagnitude(false);
2024-07-05 11:00:39 +00:00
contourmapper->setMagnitude(false);
2024-05-20 17:42:22 +00:00
filter->changeWindComponent(1);
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue));
contourmapper->newZ(filter->passSlice(XValue,YValue), renderer->z);
2024-05-20 17:42:22 +00:00
} else if (e->key() == Qt::Key_Z) {
mapper->setMagnitude(false);
2024-07-05 11:00:39 +00:00
contourmapper->setMagnitude(false);
2024-05-20 17:42:22 +00:00
filter->changeWindComponent(2);
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue));
contourmapper->newZ(filter->passSlice(XValue,YValue), renderer->z);
2024-05-20 17:42:22 +00:00
} else if (e->key() == Qt::Key_M) {
// SPECIAL CASE
filter->changeWindComponent(0);
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue));
2024-05-20 17:42:22 +00:00
mapper->setMagnitude(true);
2024-07-05 11:00:39 +00:00
contourmapper->setMagnitude(true);
} else if (e->key() == Qt::Key_Right) {
std::cout << "Right press\n";
grid->updateT();
} else if (e->key() == Qt::Key_Left) {
grid->decreaseT();
2024-06-19 15:01:53 +00:00
} else if (e->key() == Qt::Key_Space) {
if (!animate) {
animate = !animate;
timey->start(34); // 30Hz/FPS
std::cout << "Animation started\n";
} else {
timey->stop();
animate = !animate;
std::cout << "Animation closed\n";
}
} else if (e->key() == Qt::Key_R){
grid->resetT();
} else {
2024-05-20 17:42:22 +00:00
return;
}
// Redraw OpenGL.
update();
}
void OpenGLDisplayWidget::updateMVPMatrix()
{
// Calculate a simple model view transformation from rotation angles
// and distance to camera.
// NOTE: Read from bottom to top.
QMatrix4x4 mvMatrix;
mvMatrix.translate(0.0, 0.0, distanceToCamera);
mvMatrix.rotate(rotationAngles.y(), QVector3D(1.0, 0.0, 0.0));
mvMatrix.rotate(rotationAngles.x(), QVector3D(0.0, 1.0, 0.0));
mvMatrix.translate(-1.0, -1.0, -1.0);
mvMatrix.scale(2.0);
mvpMatrix = projectionMatrix * mvMatrix;
}
2024-06-19 15:01:53 +00:00
void OpenGLDisplayWidget::animateVisual() {
grid->updateT();
update();
}
2024-05-20 17:42:22 +00:00
void OpenGLDisplayWidget::initVisualizationPipeline()
{
// Initialize the visualization pipeline:
// Initialize data source(s).
grid = new FlowDataSource();
2024-06-15 18:50:23 +00:00
grid->createData(XValue,YValue,ZValue, 0);
2024-05-20 17:42:22 +00:00
// Initialize filter modules.
filter = new CartesianGridToHorizontalSliceFilter();
filter->setDataSource(grid->returnSource());
2024-06-15 18:50:23 +00:00
filter->setSlice(0);
2024-05-20 17:42:22 +00:00
filter->setWindComponent(0); // The x-component
// Initialize mapper modules.
mapper = new HorizontalSliceToImageMapper();
2024-06-15 18:50:23 +00:00
mapper->getSlice(filter->passSlice(XValue,YValue), XValue,YValue);
2024-05-20 17:42:22 +00:00
2024-07-05 11:00:39 +00:00
contourmapper = new HorizontalSliceToContourLineMapper(); //Mapper caused the program to crash, but not anymore
2024-06-15 18:50:23 +00:00
contourmapper->getSlice(filter->passSlice(XValue,YValue), XValue,YValue,ZValue, 0);
float *isos = new float[3];
2024-06-11 11:02:20 +00:00
isos[0] = 0.1;
2024-06-15 18:50:23 +00:00
isos[1] = 0;
isos[2] = -0.1;
contourmapper->setIso(isos, 3);
2024-06-11 11:02:20 +00:00
delete[] isos;
2024-07-05 11:00:39 +00:00
streamlinemapper = new StreamlineMapper();
streamlinemapper->getData(filter->passCube(), XValue, YValue, ZValue);
2024-07-05 19:38:40 +00:00
streamlinemapper->setValues(1000, 100);
//streamlinemapper->setValues(125, 100);
2024-07-05 11:00:39 +00:00
2024-06-11 11:02:20 +00:00
2024-05-20 17:42:22 +00:00
// Initialize rendering modules.
//bboxRenderer = new DataVolumeBoundingBoxRenderer();
2024-06-15 18:50:23 +00:00
renderer = new HorizontalSliceRenderer(0, ZValue);
2024-06-11 11:02:20 +00:00
contourrenderer = new HorizontalContourLinesRenderer();
2024-05-20 17:42:22 +00:00
renderer->setMapper(mapper);
2024-06-11 11:02:20 +00:00
contourrenderer->setContourMapper(contourmapper);
2024-07-05 11:00:39 +00:00
streamlinerenderer = new StreamlineRenderer();
streamlinerenderer->setMapper(streamlinemapper);
2024-05-20 17:42:22 +00:00
}