aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/4dshapes/4dsphere.cpp37
-rw-r--r--src/mainwindow.cpp170
-rw-r--r--src/mainwindow.h15
-rw-r--r--src/raytracer/raytracer.cpp174
-rw-r--r--src/raytracer/raytracer.h16
-rw-r--r--src/settings.h2
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;
};