aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/camera/camera.cpp33
-rw-r--r--src/mainwindow.cpp14
-rw-r--r--src/raytracer/raytracer.cpp90
-rw-r--r--src/utils/sceneparser.cpp82
4 files changed, 151 insertions, 68 deletions
diff --git a/src/camera/camera.cpp b/src/camera/camera.cpp
index 4c19663..b2d4b12 100644
--- a/src/camera/camera.cpp
+++ b/src/camera/camera.cpp
@@ -1,6 +1,7 @@
#include <stdexcept>
#include "camera.h"
#include "vec4ops/vec4ops.h"
+#include "settings.h"
Camera::Camera(SceneCameraData cameraData) :
m_pos(cameraData.pos),
@@ -8,11 +9,37 @@ Camera::Camera(SceneCameraData cameraData) :
m_focalLength(cameraData.focalLength),
m_aperture(cameraData.aperture)
{
- m_viewMatrix = Vec4Ops::getViewMatrix4(cameraData.pos, glm::vec4(0.f), cameraData.up, cameraData.look);
- m_translationVector = glm::vec4{-cameraData.pos.x, -cameraData.pos.y, -cameraData.pos.z, -cameraData.pos.w};
+ // m_viewMatrix = Vec4Ops::getViewMatrix4(cameraData.pos, glm::vec4(0.f), cameraData.up, cameraData.look);
+ // m_translationVector = glm::vec4{-cameraData.pos.x, -cameraData.pos.y, -cameraData.pos.z, -cameraData.pos.w};
+
+ // m_inverseViewMatrix = glm::inverse(m_viewMatrix);
+ // m_inverseTranslationVector = -m_translationVector;
+ glm::vec3 look3{cameraData.look.x, cameraData.look.y, cameraData.look.z};
+ glm::vec3 up3{cameraData.up.x, cameraData.up.y, cameraData.up.z};
+
+ // calculate new basis
+ glm::vec3 e0 = -glm::normalize(look3);
+ glm::vec3 e1 = glm::normalize(up3 - glm::dot(up3, e0) * e0);
+ glm::vec3 e2 = glm::cross(e1, e0);
+
+ glm::mat4 alignment
+ {
+ e2.x, e1.x, e0.x, 0.f,
+ e2.y, e1.y, e0.y, 0.f,
+ e2.z, e1.z, e0.z, 0.f,
+ 0.f, 0.f, 0.f, 1.f
+ };
+ glm::mat4 translation
+ {
+ 1.f, 0.f, 0.f, 0.f,
+ 0.f, 1.f, 0.f, 0.f,
+ 0.f, 0.f, 1.f, 0.f,
+ -cameraData.pos.x, -cameraData.pos.y, -cameraData.pos.z, 1.f
+ };
+
+ m_viewMatrix = alignment * translation;
m_inverseViewMatrix = glm::inverse(m_viewMatrix);
- m_inverseTranslationVector = -m_translationVector;
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index fafe7ad..959862d 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -208,15 +208,15 @@ void MainWindow::initialize() {
QHBoxLayout *lw = new QHBoxLayout();
wSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
- wSlider->setTickInterval(1);
- wSlider->setMinimum(-5000);
- wSlider->setMaximum(5000);
+ wSlider->setTickInterval(0.01);
+ wSlider->setMinimum(-500);
+ wSlider->setMaximum(500);
wSlider->setValue(0);
wBox = new QDoubleSpinBox();
- wBox->setMinimum(-50.0f);
- wBox->setMaximum(50.f);
- wBox->setSingleStep(1.f);
+ wBox->setMinimum(-5.0f);
+ wBox->setMaximum(5.f);
+ wBox->setSingleStep(0.01f);
wBox->setValue(0.f);
lw->addWidget(wSlider);
@@ -247,6 +247,8 @@ void MainWindow::initialize() {
connectUIElements();
+
+ onValChangeWSlider(0);
}
void MainWindow::finish() {
diff --git a/src/raytracer/raytracer.cpp b/src/raytracer/raytracer.cpp
index 8bcf6ba..acb229a 100644
--- a/src/raytracer/raytracer.cpp
+++ b/src/raytracer/raytracer.cpp
@@ -27,39 +27,39 @@ RayTracer::RayTracer(QWidget *parent) : QWidget(parent) {
void RayTracer::render(RGBA *imageData, const RayTraceScene &scene) {
if (m_enableParallelism) {
renderParallel(imageData, scene);
- }
-
- // naive rendering
- Camera camera = scene.getCamera();
- float cameraDepth = 1.f;
-
- float viewplaneHeight = 2.f*cameraDepth*std::tan(camera.getHeightAngle() / 2.f);
- float viewplaneWidth = cameraDepth*viewplaneHeight*((float)scene.width()/(float)scene.height());
-
- for (int imageRow = 0; imageRow < scene.height(); imageRow++) {
- for (int imageCol = 0; imageCol < scene.width(); imageCol++) {
- // FIXME: for now, use height as depth
- for (int imageDepth = 0; imageDepth < scene.height(); imageDepth++) {
- // compute the ray
- float x = (imageCol - scene.width()/2.f) * viewplaneWidth / scene.width();
- float y = (imageRow - scene.height()/2.f) * viewplaneHeight / scene.height();
- float z = (imageDepth - scene.height()/2.f) * viewplaneHeight / scene.height();
- float camera4dDepth = 1;
-
- glm::vec4 pWorld = Vec4Ops::transformPoint4(glm::vec4(x, y, z, 0.f), camera.getViewMatrix(), camera.getTranslationVector());
- glm::vec4 dWorld = glm::vec4(0.f, 0.f, 0.f, -1.f);
-
- // get the pixel color
- glm::vec4 pixelColor = getPixelFromRay(pWorld, dWorld, scene, 0);
-
- // set the pixel color
- int index = imageRow * scene.width() + imageCol;
- imageData[index] = RGBA{
- (std::uint8_t) (pixelColor.r * 255.f),
- (std::uint8_t) (pixelColor.g * 255.f),
- (std::uint8_t) (pixelColor.b * 255.f),
- (std::uint8_t) (pixelColor.a * 255.f)
- };
+ } else {
+ // naive rendering
+ Camera camera = scene.getCamera();
+ float cameraDepth = 1.f;
+
+ float viewplaneHeight = 2.f*cameraDepth*std::tan(camera.getHeightAngle() / 2.f);
+ float viewplaneWidth = cameraDepth*viewplaneHeight*((float)scene.width()/(float)scene.height());
+
+ for (int imageRow = 0; imageRow < scene.height(); imageRow++) {
+ for (int imageCol = 0; imageCol < scene.width(); imageCol++) {
+ // FIXME: for now, use height as depth
+ for (int imageDepth = 0; imageDepth < scene.height(); imageDepth++) {
+ // compute the ray
+ float x = (imageCol - scene.width()/2.f) * viewplaneWidth / scene.width();
+ float y = (imageRow - scene.height()/2.f) * viewplaneHeight / scene.height();
+ float z = (imageDepth - scene.height()/2.f) * viewplaneHeight / scene.height();
+ float camera4dDepth = 1;
+
+ glm::vec4 pWorld = Vec4Ops::transformPoint4(glm::vec4(x, y, z, 0.f), camera.getViewMatrix(), camera.getTranslationVector());
+ glm::vec4 dWorld = glm::vec4(0.f, 0.f, 0.f, -1.f);
+
+ // get the pixel color
+ glm::vec4 pixelColor = getPixelFromRay(pWorld, dWorld, scene, 0);
+
+ // set the pixel color
+ int index = imageRow * scene.width() + imageCol;
+ imageData[index] = RGBA{
+ (std::uint8_t) (pixelColor.r * 255.f),
+ (std::uint8_t) (pixelColor.g * 255.f),
+ (std::uint8_t) (pixelColor.b * 255.f),
+ (std::uint8_t) (pixelColor.a * 255.f)
+ };
+ }
}
}
}
@@ -99,7 +99,7 @@ glm::vec4 RayTracer::getPixelFromRay(
for (const RenderShapeData &shape : scene.getShapes()) {
glm::vec4 pObject = shape.inverseCTM * pWorld;
glm::vec4 dObject = glm::normalize(shape.inverseCTM * dWorld);
-
+ std::cout << "pObject: " << pObject.w << std::endl;
glm::vec4 newIntersectionObj = findIntersection(pObject, dObject, shape);
if (newIntersectionObj.w == 0) // no hit
{
@@ -175,6 +175,11 @@ void RayTracer::sceneChanged(QLabel* imageLabel) {
if (!success) {
std::cerr << "Error loading scene: \"" << settings.sceneFilePath << "\"" << std::endl;
+ // return;
+ QImage image = QImage(576, 432, QImage::Format_RGBX8888);
+ image.fill(Qt::black);
+ RGBA *data = reinterpret_cast<RGBA *>(image.bits());
+ imageLabel->setPixmap(QPixmap::fromImage(image));
return;
}
@@ -192,13 +197,26 @@ void RayTracer::sceneChanged(QLabel* imageLabel) {
QImage flippedImage = image.mirrored(false, false);
// make the image larger
- flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ flippedImage = flippedImage.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
imageLabel->setPixmap(QPixmap::fromImage(flippedImage));
m_imageLabel = imageLabel;
}
void RayTracer::settingsChanged(QLabel* imageLabel) {
+ bool success = SceneParser::parse(settings.sceneFilePath, m_metaData);
+
+ if (!success) {
+ std::cerr << "Error loading scene: \"" << settings.sceneFilePath << "\"" << std::endl;
+ // return;
+ // render a blank image
+ QImage image = QImage(576, 432, QImage::Format_RGBX8888);
+ image.fill(Qt::black);
+ RGBA *data = reinterpret_cast<RGBA *>(image.bits());
+ imageLabel->setPixmap(QPixmap::fromImage(image));
+ return;
+ }
+
int width = 576;
int height = 432;
@@ -210,7 +228,7 @@ void RayTracer::settingsChanged(QLabel* imageLabel) {
this->render(data, rtScene);
QImage flippedImage = image.mirrored(false, false);
- flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ flippedImage = flippedImage.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
imageLabel->setPixmap(QPixmap::fromImage(flippedImage));
}
diff --git a/src/utils/sceneparser.cpp b/src/utils/sceneparser.cpp
index 5eddf93..009873b 100644
--- a/src/utils/sceneparser.cpp
+++ b/src/utils/sceneparser.cpp
@@ -4,6 +4,7 @@
#include <glm/gtx/transform.hpp>
#include <QImage>
#include <iostream>
+#include "../settings.h"
/**
@@ -36,18 +37,28 @@ TextureData loadTextureFromFile(const QString &file) {
// helper to handle recursive creation of tree
void initTree(SceneNode* currentNode, std::vector<RenderShapeData> *shapes, std::vector<SceneLightData> *lights, glm::mat4 currentCTM, glm::vec4 currentTranslation4d) {
+ if (currentNode->transformations.size() == 0) {
+ // ScenePa.rser::translate4(currentTranslation4d, glm::vec4(0.f, 0.f, 0.f, settings.w));
+ // convert currentTranslation4d to a 4x4 matrix
+ currentCTM = glm::translate(glm::mat4(1.0f), glm::vec3(currentTranslation4d));
+ currentCTM *= SceneParser::getRotationMatrix4(1.f, glm::vec3(settings.xy, settings.xz, settings.yz), glm::vec3(settings.xw, settings.yw, settings.zw));
+ }
+
+ SceneParser::translate4(currentTranslation4d, glm::vec4(0.f, 0.f, 0.f, settings.w));
+
for (auto t : currentNode->transformations) {
switch (t->type)
{
case TransformationType::TRANSFORMATION_TRANSLATE:
- SceneParser::translate4(currentTranslation4d, t->translate);
- break;
- case TransformationType::TRANSFORMATION_SCALE:
- SceneParser::scale4(currentCTM, t->scale);
+ SceneParser::translate4(currentTranslation4d, glm::vec4(t->translate.xyz(), 0.f));
+ // currentCTM = glm::translate(glm::mat4(1.0f), glm::vec3(currentTranslation4d));
break;
case TransformationType::TRANSFORMATION_ROTATE:
currentCTM *= SceneParser::getRotationMatrix4(t->angle, t->rotate3, t->rotateW);
break;
+ case TransformationType::TRANSFORMATION_SCALE:
+ SceneParser::scale4(currentCTM, t->scale);
+ break;
case TransformationType::TRANSFORMATION_MATRIX:
currentCTM *= glm::mat4(t->matrix);
currentTranslation4d *= glm::vec4(t->matrixRight4d); // TODO
@@ -58,6 +69,8 @@ void initTree(SceneNode* currentNode, std::vector<RenderShapeData> *shapes, std:
}
}
+ currentCTM *= glm::translate(glm::mat4(1.0f), glm::vec3(currentTranslation4d));
+
for(auto primitive : currentNode->primitives) {
// primitive->material.textureData = loadTextureFromFile(QString::fromStdString(primitive->material.textureMap.filename));
@@ -144,25 +157,48 @@ bool SceneParser::parse(std::string filepath, RenderData &renderData) {
return true;
}
-glm::mat4 SceneParser::getRotationMatrix4(
- float angle,
- glm::vec3 axis3,
- glm::vec3 axisW) {
- // start with the normal rotation from the normal 3d axes
- if (axis3.x > 0)
- return Vec4Ops::getRotationMatrix4XY(angle);
- else if (axis3.y > 0)
- return Vec4Ops::getRotationMatrix4YZ(angle);
- else if (axis3.z > 0)
- return Vec4Ops::getRotationMatrix4ZX(angle);
- else if (axisW.x > 0)
- return Vec4Ops::getRotationMatrix4XW(angle);
- else if (axisW.y > 0)
- return Vec4Ops::getRotationMatrix4YW(angle);
- else if (axisW.z > 0)
- return Vec4Ops::getRotationMatrix4ZW(angle);
- else
- throw std::runtime_error("invalid axis");
+// glm::mat4 SceneParser::getRotationMatrix4(
+// float angle,
+// glm::vec3 axis3,
+// glm::vec3 axisW) {
+// // start with the normal rotation from the normal 3d axes
+// if (axis3.x > 0)
+// return Vec4Ops::getRotationMatrix4XY(angle);
+// else if (axis3.y > 0)
+// return Vec4Ops::getRotationMatrix4YZ(angle);
+// else if (axis3.z > 0)
+// return Vec4Ops::getRotationMatrix4ZX(angle);
+// else if (axisW.x > 0)
+// return Vec4Ops::getRotationMatrix4XW(angle);
+// else if (axisW.y > 0)
+// return Vec4Ops::getRotationMatrix4YW(angle);
+// else if (axisW.z > 0)
+// return Vec4Ops::getRotationMatrix4ZW(angle);
+// else
+// throw std::runtime_error("invalid axis");
+// }
+
+glm::mat4 SceneParser::getRotationMatrix4(float angle, glm::vec3 axis3, glm::vec3 axisW) {
+ glm::mat4 rotationMatrix3D = glm::mat4(1.0f); // Identity matrix
+
+ // convert axis3 and axisW to radians
+ axis3 = glm::radians(axis3);
+ axisW = glm::radians(axisW);
+
+ // Apply 3D rotations if any axis is non-zero
+ if (axis3.x != 0) rotationMatrix3D *= glm::rotate(axis3.x, glm::vec3(1, 0, 0));
+ if (axis3.y != 0) rotationMatrix3D *= glm::rotate(axis3.y, glm::vec3(0, 1, 0));
+ if (axis3.z != 0) rotationMatrix3D *= glm::rotate(axis3.z, glm::vec3(0, 0, 1));
+
+ glm::mat4 rotationMatrix4D = glm::mat4(1.0f); // Identity matrix
+
+ // Apply 4D rotations if any axis is non-zero
+ if (axisW.x != 0) rotationMatrix4D *= Vec4Ops::getRotationMatrix4XW(axisW.x);
+ if (axisW.y != 0) rotationMatrix4D *= Vec4Ops::getRotationMatrix4YW(axisW.y);
+ if (axisW.z != 0) rotationMatrix4D *= Vec4Ops::getRotationMatrix4ZW(axisW.z);
+
+ // Combine both 3D and 4D rotations
+ return rotationMatrix4D * rotationMatrix3D;
}
void SceneParser::translate4(