diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/4dshapes/4dsphere.cpp | 37 | ||||
-rw-r--r-- | src/mainwindow.cpp | 170 | ||||
-rw-r--r-- | src/mainwindow.h | 15 | ||||
-rw-r--r-- | src/raytracer/raytracer.cpp | 174 | ||||
-rw-r--r-- | src/raytracer/raytracer.h | 16 | ||||
-rw-r--r-- | src/settings.h | 2 |
6 files changed, 381 insertions, 33 deletions
diff --git a/src/4dshapes/4dsphere.cpp b/src/4dshapes/4dsphere.cpp new file mode 100644 index 0000000..4ebe2ba --- /dev/null +++ b/src/4dshapes/4dsphere.cpp @@ -0,0 +1,37 @@ +#include "raytracer/raytracer.h" + +// vector operations on 4d vectors, +// reference: https://hollasch.github.io/ray4/Four-Space_Visualization_of_4D_Objects.html#chapter5 + +bool HitSphere(RenderShapeData object, glm::vec4 rayOrigin, glm::vec4 rayDirection, glm::vec4 inter) { + float bb; + glm::vec4 cdir; + float rad; + float t1, t2; + + cdir = object.ctm * glm::vec4(0.f,0.f,0.f,1.f) - rayOrigin; + bb = glm::dot(cdir, rayDirection); + rad = (bb * bb) - glm::dot(cdir, cdir) + 0.25f; + + if (rad < 0.0) { + return false; + } + + rad = sqrt(rad); + t2 = bb - rad; + t1 = bb + rad; + + if ((t1 < 0.0) || ((t2 > 0.0) && (t2 < t1))) { + t1 = t2; + } + + if (t1 <= 0.0) { + return false; + } + + if (inter != glm::vec4(0.f,0.f,0.f, 1.f)) { + inter = rayOrigin + t1 * rayDirection; + } + + return true; +}
\ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 45c1c2c..5da720b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -43,6 +43,10 @@ void MainWindow::initialize() { QLabel *zw_label = new QLabel(); // ZW label zw_label->setText("ZW value:"); zw_label->setFont(font); + + QLabel *rotation_label = new QLabel(); // Rotation label + rotation_label->setText("Rotation value:"); + rotation_label->setFont(font); // Create file uploader for scene file @@ -57,14 +61,14 @@ void MainWindow::initialize() { xySlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider xySlider->setTickInterval(1); - xySlider->setMinimum(-1000); - xySlider->setMaximum(1000); + xySlider->setMinimum(-36000); + xySlider->setMaximum(36000); xySlider->setValue(0); xyBox = new QDoubleSpinBox(); - xyBox->setMinimum(-10.0f); - xyBox->setMaximum(10.f); - xyBox->setSingleStep(0.1f); + xyBox->setMinimum(-360.0f); + xyBox->setMaximum(360.f); + xyBox->setSingleStep(1.f); xyBox->setValue(0.f); lxy->addWidget(xySlider); @@ -77,14 +81,14 @@ void MainWindow::initialize() { xzSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider xzSlider->setTickInterval(1); - xzSlider->setMinimum(-1000); - xzSlider->setMaximum(1000); + xzSlider->setMinimum(-36000); + xzSlider->setMaximum(36000); xzSlider->setValue(0); xzBox = new QDoubleSpinBox(); - xzBox->setMinimum(-10.0f); - xzBox->setMaximum(10.f); - xzBox->setSingleStep(0.1f); + xzBox->setMinimum(-360.0f); + xzBox->setMaximum(360.f); + xzBox->setSingleStep(1.f); xzBox->setValue(0.f); lxz->addWidget(xzSlider); @@ -97,14 +101,14 @@ void MainWindow::initialize() { xwSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider xwSlider->setTickInterval(1); - xwSlider->setMinimum(-1000); - xwSlider->setMaximum(1000); + xwSlider->setMinimum(-36000); + xwSlider->setMaximum(36000); xwSlider->setValue(0); xwBox = new QDoubleSpinBox(); - xwBox->setMinimum(-10.0f); - xwBox->setMaximum(10.f); - xwBox->setSingleStep(0.1f); + xwBox->setMinimum(-360.0f); + xwBox->setMaximum(360.f); + xwBox->setSingleStep(1.f); xwBox->setValue(0.f); lxw->addWidget(xwSlider); @@ -117,14 +121,14 @@ void MainWindow::initialize() { yzSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider yzSlider->setTickInterval(1); - yzSlider->setMinimum(-1000); - yzSlider->setMaximum(1000); + yzSlider->setMinimum(-36000); + yzSlider->setMaximum(36000); yzSlider->setValue(0); yzBox = new QDoubleSpinBox(); - yzBox->setMinimum(-10.0f); - yzBox->setMaximum(10.f); - yzBox->setSingleStep(0.1f); + yzBox->setMinimum(-360.0f); + yzBox->setMaximum(360.f); + yzBox->setSingleStep(1.f); yzBox->setValue(0.f); lyz->addWidget(yzSlider); @@ -137,15 +141,15 @@ void MainWindow::initialize() { ywSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider ywSlider->setTickInterval(1); - ywSlider->setMinimum(-1000); - ywSlider->setMaximum(1000); + ywSlider->setMinimum(-36000); + ywSlider->setMaximum(36000); ywSlider->setValue(0); ywBox = new QDoubleSpinBox(); - ywBox->setMinimum(-10.0f); - ywBox->setMaximum(10.f); - ywBox->setSingleStep(0.1f); - ywBox->setValue(100.f); + ywBox->setMinimum(-360.0f); + ywBox->setMaximum(360.f); + ywBox->setSingleStep(1.f); + ywBox->setValue(0.f); lyw->addWidget(ywSlider); lyw->addWidget(ywBox); @@ -157,20 +161,45 @@ void MainWindow::initialize() { zwSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider zwSlider->setTickInterval(1); - zwSlider->setMinimum(-1000); - zwSlider->setMaximum(1000); + zwSlider->setMinimum(-36000); + zwSlider->setMaximum(36000); zwSlider->setValue(0); zwBox = new QDoubleSpinBox(); - zwBox->setMinimum(-10.0f); - zwBox->setMaximum(10.f); - zwBox->setSingleStep(0.1f); - zwBox->setValue(100.f); + zwBox->setMinimum(-360.0f); + zwBox->setMaximum(360.f); + zwBox->setSingleStep(1.f); + zwBox->setValue(0.f); lzw->addWidget(zwSlider); lzw->addWidget(zwBox); zwLayout->setLayout(lzw); + // Rotation Slider + QGroupBox *rotationLayout = new QGroupBox(); // horizonal w slider alignment + QHBoxLayout *lrotation = new QHBoxLayout(); + + rotationSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider + rotationSlider->setTickInterval(1); + rotationSlider->setMinimum(0); + rotationSlider->setMaximum(18000); + rotationSlider->setValue(1); + + rotationBox = new QDoubleSpinBox(); + rotationBox->setMinimum(0.0f); + rotationBox->setMaximum(180.f); + rotationBox->setSingleStep(1.f); + rotationBox->setValue(1.f); + + lrotation->addWidget(rotationSlider); + lrotation->addWidget(rotationBox); + rotationLayout->setLayout(lrotation); + + // checkbox + rotateNegative = new QCheckBox(); + rotateNegative->setText(QStringLiteral("Reverse Rotation")); + rotateNegative->setChecked(false); + vLayout->addWidget(uploadFile); vLayout->addWidget(saveImage); vLayout->addWidget(xy_label); @@ -185,6 +214,10 @@ void MainWindow::initialize() { vLayout->addWidget(ywLayout); vLayout->addWidget(zw_label); vLayout->addWidget(zwLayout); + vLayout->addWidget(rotation_label); + vLayout->addWidget(rotationLayout); + + vLayout->addWidget(rotateNegative); connectUIElements(); @@ -194,6 +227,7 @@ void MainWindow::initialize() { onValChangeyzBox(0.0f); onValChangeywBox(0.0f); onValChangezwBox(0.0f); + onValChangeRotationBox(1.0f); } void MainWindow::finish() { @@ -210,6 +244,14 @@ void MainWindow::connectUIElements() { connectyz(); connectyw(); connectzw(); + connectRotationSlider(); + connectNegativeRotation(); + connect(rayTracer, &RayTracer::xyRotationChanged, this, &MainWindow::updateXySlider); + connect(rayTracer, &RayTracer::xzRotationChanged, this, &MainWindow::updateXzSlider); + connect(rayTracer, &RayTracer::xwRotationChanged, this, &MainWindow::updateXwSlider); + connect(rayTracer, &RayTracer::yzRotationChanged, this, &MainWindow::updateYzSlider); + connect(rayTracer, &RayTracer::ywRotationChanged, this, &MainWindow::updateYwSlider); + connect(rayTracer, &RayTracer::zwRotationChanged, this, &MainWindow::updateZwSlider); } void MainWindow::connectUploadFile() { @@ -256,6 +298,16 @@ void MainWindow::connectzw() { this, &MainWindow::onValChangezwBox); } +void MainWindow::connectRotationSlider() { + connect(rotationSlider, &QSlider::valueChanged, this, &MainWindow::onValChangeRotationSlider); + connect(rotationBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), + this, &MainWindow::onValChangeRotationBox); +} + +void MainWindow::connectNegativeRotation() { + connect(rotateNegative, &QCheckBox::clicked, this, &MainWindow::onRotateNegative); +} + void MainWindow::onUploadFile() { // Get abs path of scene file QString configFilePath = QFileDialog::getOpenFileName(this, tr("Upload File"), @@ -382,3 +434,57 @@ void MainWindow::onValChangezwBox(double newValue) { settings.zw = zwBox->value(); rayTracer->settingsChanged(imageLabel); } + +void MainWindow::onValChangeRotationSlider(int newValue) { + //wSlider->setValue(newValue); + rotationBox->setValue(newValue/100.f); + settings.rotation = rotationBox->value(); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::onValChangeRotationBox(double newValue) { + rotationSlider->setValue(int(newValue*100.f)); + //wBox->setValue(newValue); + settings.rotation = rotationBox->value(); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::onRotateNegative() { + settings.negative = !settings.negative; +} + +void MainWindow::updateXySlider(double value) { + xySlider->setValue(int(value*100.f)); + xyBox->setValue(value); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::updateXzSlider(double value) { + xzSlider->setValue(int(value*100.f)); + xzBox->setValue(value); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::updateXwSlider(double value) { + xwSlider->setValue(int(value*100.f)); + xwBox->setValue(value); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::updateYzSlider(double value) { + yzSlider->setValue(int(value*100.f)); + yzBox->setValue(value); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::updateYwSlider(double value) { + ywSlider->setValue(int(value*100.f)); + ywBox->setValue(value); + rayTracer->settingsChanged(imageLabel); +} + +void MainWindow::updateZwSlider(double value) { + zwSlider->setValue(int(value*100.f)); + zwBox->setValue(value); + rayTracer->settingsChanged(imageLabel); +}
\ No newline at end of file diff --git a/src/mainwindow.h b/src/mainwindow.h index 6c98ae2..35498ee 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -30,6 +30,8 @@ private: void connectyz(); void connectyw(); void connectzw(); + void connectRotationSlider(); + void connectNegativeRotation(); RayTracer *rayTracer; AspectRatioWidget *aspectRatioWidget; @@ -47,6 +49,10 @@ private: QDoubleSpinBox *ywBox; QSlider *zwSlider; QDoubleSpinBox *zwBox; + QSlider *rotationSlider; + QDoubleSpinBox *rotationBox; + QCheckBox *rotateNegative; + private slots: void onUploadFile(); @@ -63,4 +69,13 @@ private slots: void onValChangeywBox(double newValue); void onValChangezwSlider(int newValue); void onValChangezwBox(double newValue); + void onValChangeRotationSlider(int newValue); + void onValChangeRotationBox(double newValue); + void onRotateNegative(); + void updateXySlider(double newValue); + void updateXzSlider(double newValue); + void updateXwSlider(double newValue); + void updateYzSlider(double newValue); + void updateYwSlider(double newValue); + void updateZwSlider(double newValue); }; diff --git a/src/raytracer/raytracer.cpp b/src/raytracer/raytracer.cpp index 93f5225..435af74 100644 --- a/src/raytracer/raytracer.cpp +++ b/src/raytracer/raytracer.cpp @@ -5,6 +5,8 @@ #include "raytracescene.h" #include "settings.h" #include "mainwindow.h" +#include <QKeyEvent> +#include <QTimerEvent> //struct Ray { // glm::vec3 p; @@ -12,7 +14,20 @@ //}; // RayTracer::RayTracer(const Config &config) : m_config(config) {} -RayTracer::RayTracer(QWidget *parent) : QWidget(parent) {} +RayTracer::RayTracer(QWidget *parent) : QWidget(parent) { + setFocusPolicy(Qt::StrongFocus); + + // map the 1 key + m_keyMap[Qt::Key_1] = false; + m_keyMap[Qt::Key_2] = false; + m_keyMap[Qt::Key_3] = false; + m_keyMap[Qt::Key_4] = false; + m_keyMap[Qt::Key_5] = false; + m_keyMap[Qt::Key_6] = false; + + // m_timer = startTimer(1000/60); + // m_elapsedTimer.start(); +} void RayTracer::render(RGBA *imageData, const RayTraceScene &scene) { if(m_enableParallelism) @@ -181,6 +196,8 @@ void RayTracer::sceneChanged(QLabel* imageLabel) { // make the image larger flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); imageLabel->setPixmap(QPixmap::fromImage(flippedImage)); + + m_imageLabel = imageLabel; } void RayTracer::settingsChanged(QLabel* imageLabel) { @@ -199,4 +216,159 @@ void RayTracer::settingsChanged(QLabel* imageLabel) { imageLabel->setPixmap(QPixmap::fromImage(flippedImage)); } +void RayTracer::keyPressEvent(QKeyEvent *event) { + m_keyMap[Qt::Key(event->key())] = true; + std::cout << "key pressed" << std::endl; + if (m_keyMap[Qt::Key_1]) { + std::cout << "key 1" << std::endl; + if (settings.negative) { + settings.xy -= settings.rotation; + } else { + settings.xy += settings.rotation; + } + emit xyRotationChanged(settings.xy); + } + + if (m_keyMap[Qt::Key_2]) { + if (settings.negative) { + settings.xz -= settings.rotation; + } else { + settings.xz += settings.rotation; + } + emit xzRotationChanged(settings.xz); + } + + if (m_keyMap[Qt::Key_3]) { + if (settings.negative) { + settings.xw -= settings.rotation; + } else { + settings.xw += settings.rotation; + } + emit xwRotationChanged(settings.xw); + } + + if (m_keyMap[Qt::Key_4]) { + if (settings.negative) { + settings.yz -= settings.rotation; + } else { + settings.yz += settings.rotation; + } + emit yzRotationChanged(settings.yz); + } + + if (m_keyMap[Qt::Key_5]) { + if (settings.negative) { + settings.yw -= settings.rotation; + } else { + settings.yw += settings.rotation; + } + emit ywRotationChanged(settings.yw); + } + + if (m_keyMap[Qt::Key_6]) { + if (settings.negative) { + settings.zw -= settings.rotation; + } else { + settings.zw += settings.rotation; + } + emit zwRotationChanged(settings.zw); + } + + + // std::cout << "key done" << std::endl; + + // int width = 576; + // int height = 432; + + // QImage image = QImage(width, height, QImage::Format_RGBX8888); + // image.fill(Qt::black); + // RGBA *data = reinterpret_cast<RGBA *>(image.bits()); + + // RayTraceScene rtScene{ width, height, m_metaData }; + // this->render(data, rtScene); + + // std::cout << "done rendering" << std::endl; + + // QImage flippedImage = image.mirrored(false, false); + // flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + // m_imageLabel->setPixmap(QPixmap::fromImage(flippedImage)); +} + +void RayTracer::keyReleaseEvent(QKeyEvent *event) { + m_keyMap[Qt::Key(event->key())] = false; +} + +// void RayTracer::timerEvent(QTimerEvent *event) { +// int elapsedms = m_elapsedTimer.elapsed(); +// float deltaTime = elapsedms * 0.001f; +// m_elapsedTimer.restart(); + +// if (m_keyMap[Qt::Key_1]) { +// if (settings.negative) { +// settings.xy -= settings.rotation; +// } else { +// settings.xy += settings.rotation; +// } +// emit xyRotationChanged(settings.xy); +// } + +// if (m_keyMap[Qt::Key_2]) { +// if (settings.negative) { +// settings.xz -= settings.rotation; +// } else { +// settings.xz += settings.rotation; +// } +// emit xzRotationChanged(settings.xz); +// } + +// if (m_keyMap[Qt::Key_3]) { +// if (settings.negative) { +// settings.xw -= settings.rotation; +// } else { +// settings.xw += settings.rotation; +// } +// emit xwRotationChanged(settings.xw); +// } + +// if (m_keyMap[Qt::Key_4]) { +// if (settings.negative) { +// settings.yz -= settings.rotation; +// } else { +// settings.yz += settings.rotation; +// } +// emit yzRotationChanged(settings.yz); +// } + +// if (m_keyMap[Qt::Key_5]) { +// if (settings.negative) { +// settings.yw -= settings.rotation; +// } else { +// settings.yw += settings.rotation; +// } +// emit ywRotationChanged(settings.yw); +// } + +// if (m_keyMap[Qt::Key_6]) { +// if (settings.negative) { +// settings.zw -= settings.rotation; +// } else { +// settings.zw += settings.rotation; +// } +// emit zwRotationChanged(settings.zw); +// } + +// int width = 576; +// int height = 432; + +// QImage image = QImage(width, height, QImage::Format_RGBX8888); +// image.fill(Qt::black); +// RGBA *data = reinterpret_cast<RGBA *>(image.bits()); + +// RayTraceScene rtScene{ width, height, m_metaData }; +// this->render(data, rtScene); + +// QImage flippedImage = image.mirrored(false, false); +// flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); +// m_imageLabel->setPixmap(QPixmap::fromImage(flippedImage)); +// } diff --git a/src/raytracer/raytracer.h b/src/raytracer/raytracer.h index f938dd6..4bdca6f 100644 --- a/src/raytracer/raytracer.h +++ b/src/raytracer/raytracer.h @@ -8,6 +8,7 @@ #include "accelerate/bvh.h" #include <QOpenGLWidget> #include <QLabel> +#include <QElapsedTimer> // A forward declaration for the RaytraceScene class @@ -35,6 +36,7 @@ struct Config { class RayTracer : public QWidget { + Q_OBJECT public: // constructor for the config RayTracer(QWidget *parent = nullptr); @@ -154,9 +156,23 @@ public: void sceneChanged(QLabel* imageLabel); void settingsChanged(QLabel* imageLabel); + RenderData m_metaData; + std::unordered_map<Qt::Key, bool> m_keyMap; + QElapsedTimer m_elapsedTimer; + QLabel* m_imageLabel; + + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; glm::mat4 getRotationMatrix4(float angleRadiansXY, float angleRadiansYZ, float angleRadiansZX, float angleRadiansXW, float angleRadiansYW, float angleRadiansZW); +signals: + void xyRotationChanged(float value); + void xzRotationChanged(float value); + void xwRotationChanged(float value); + void yzRotationChanged(float value); + void ywRotationChanged(float value); + void zwRotationChanged(float value); }; diff --git a/src/settings.h b/src/settings.h index ba383b3..f114226 100644 --- a/src/settings.h +++ b/src/settings.h @@ -12,6 +12,8 @@ struct Settings { float xw = 0.f; float yw = 0.f; float zw = 0.f; + float rotation = 1.f; + bool negative = false; }; |