aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-07-26 12:56:27 +0200
committerJulian T <julian@jtle.dk>2020-07-26 12:56:27 +0200
commit893176a0b18a2281abe09def716ccc3db5583c3f (patch)
treea34da79b7dc0fcdbdd39e2a3f4000cc6a1c0a896 /src
parent18960c4b88ce912e08b12182b835a7de75388b78 (diff)
Implemented object intersection and startet work on render gui
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp6
-rw-r--r--src/main.cpp23
-rw-r--r--src/object.cpp89
-rw-r--r--src/object.hpp34
-rw-r--r--src/ray.cpp17
-rw-r--r--src/ray.hpp15
-rw-r--r--src/scene.cpp4
-rw-r--r--src/scene.hpp4
-rw-r--r--src/vector.cpp53
-rw-r--r--src/vector.hpp20
10 files changed, 226 insertions, 39 deletions
diff --git a/src/common.hpp b/src/common.hpp
new file mode 100644
index 0000000..fd219bf
--- /dev/null
+++ b/src/common.hpp
@@ -0,0 +1,6 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#define ZERO_APPROX 1e-6
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
deleted file mode 100644
index 3c15429..0000000
--- a/src/main.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <SFML/Graphics/CircleShape.hpp>
-#include <SFML/Graphics/RenderWindow.hpp>
-#include <SFML/Window/Event.hpp>
-#include <SFML/Window/VideoMode.hpp>
-#include <iostream>
-
-#include <SFML/Graphics.hpp>
-
-using namespace std;
-
-int main()
-{
- cout << "Hello World!" << endl;
-
- sf::RenderWindow window(sf::VideoMode(200, 200), "Yaah working");
- sf::CircleShape shape(100.f);
-
- window.clear();
- window.draw(shape);
- window.display();
-
- return 0;
-}
diff --git a/src/object.cpp b/src/object.cpp
new file mode 100644
index 0000000..e88ae13
--- /dev/null
+++ b/src/object.cpp
@@ -0,0 +1,89 @@
+#include "object.hpp"
+
+#include <math.h>
+#include "common.hpp"
+
+Sphere::Sphere(Vec3d center, double radius) {
+ m_center = center;
+ m_radius = radius;
+}
+
+Plane::Plane(Vec3d start, Vec3d norm) {
+ m_start = start;
+ m_norm = norm;
+
+ m_norm.normalize();
+}
+
+void Object::setMaterial(std::shared_ptr<Material> m) {
+ m_mat = m;
+}
+
+Vec3d Sphere::norm_at(const Vec3d &point, const Vec3d&) const {
+ auto res = point - m_center;
+ res.normalize();
+ return res;
+}
+
+// https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+double Sphere::intersect(const Ray &ray, bool skip_dist) const {
+ // Calculate O - C used multiple places
+ auto oc = ray.m_start - m_center;
+ // Calculate components of quadratic formula
+ // a = 1 when ray.direction is a unit vector
+ auto a = 1;
+ auto b = 2 * ray.m_direction.dot(oc);
+ auto c = oc.dot(oc) - m_radius * m_radius;
+
+ // Solve quadratic function
+ auto discr = b * b - 4 * a * c;
+ if (discr < 0) {
+ // No solution
+ return -1;
+ }
+ if (skip_dist) {
+ // Do not calculate distance
+ return 1;
+ }
+
+ auto q = (b > 0) ?
+ -0.5 * (b + sqrt(discr)):
+ -0.5 * (b - sqrt(discr));
+ auto t1 = q; // Assuming a = 1
+ auto t0 = c / q;
+
+ // Find correct result
+ if (t0 <= ZERO_APPROX) {
+ t0 = t1;
+ }
+
+ if (t0 <= ZERO_APPROX) {
+ return -1;
+ }
+
+ return t0;
+}
+
+Vec3d Plane::norm_at(const Vec3d&, const Vec3d &indir) const {
+ auto scale = m_norm.dot(indir);
+ return scale > 0 ? -m_norm : m_norm;
+}
+
+// https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-plane-and-ray-disk-intersection
+// Requires that vectors are normalized
+// Skip dist is ignored as distance must be calculated
+double Plane::intersect(const Ray &ray, bool) const {
+ // If ray is parallel
+ auto nr = m_norm.dot(ray.m_direction);
+ if (abs(nr) < ZERO_APPROX) {
+ return -1;
+ }
+
+ // Calculate distance
+ auto dist = m_norm.dot(m_start - ray.m_start) / nr;
+ if (dist < 0) {
+ return -1;
+ }
+
+ return dist;
+}
diff --git a/src/object.hpp b/src/object.hpp
index 56c6968..3194dac 100644
--- a/src/object.hpp
+++ b/src/object.hpp
@@ -3,17 +3,41 @@
#include <memory>
#include "vector.hpp"
+#include "ray.hpp"
class Material {
- Vec3d color;
-
- double defuse;
- double emissive;
};
class Object {
public:
- std::shared_ptr<Material> m;
+ void setMaterial(std::shared_ptr<Material> m);
+
+ std::shared_ptr<Material> m_mat;
+
+ virtual Vec3d norm_at(const Vec3d &point, const Vec3d &indir) const = 0;
+ virtual double intersect(const Ray &ray, bool skip_dist) const = 0;
+};
+
+class Sphere : Object {
+ public:
+ Sphere(Vec3d center, double radius);
+ Vec3d norm_at(const Vec3d &point, const Vec3d &indir) const;
+ double intersect(const Ray &ray, bool skip_dist) const;
+
+ private:
+ Vec3d m_center;
+ double m_radius;
+};
+
+class Plane : Object {
+ public:
+ Plane(Vec3d start, Vec3d norm);
+ Vec3d norm_at(const Vec3d &point, const Vec3d &indir) const;
+ double intersect(const Ray &ray, bool skip_dist) const;
+
+ private:
+ Vec3d m_start;
+ Vec3d m_norm;
};
#endif
diff --git a/src/ray.cpp b/src/ray.cpp
new file mode 100644
index 0000000..7bc6201
--- /dev/null
+++ b/src/ray.cpp
@@ -0,0 +1,17 @@
+#include "ray.hpp"
+
+Ray::Ray(Vec3d start, Vec3d direction, bool normalize) {
+ m_start = start;
+ m_direction = direction;
+
+ if (normalize) {
+ m_direction.normalize();
+ }
+}
+
+Ray::Ray(Vec3d a, Vec3d b) {
+ m_start = a;
+ m_direction = b - a;
+
+ m_direction.normalize();
+}
diff --git a/src/ray.hpp b/src/ray.hpp
new file mode 100644
index 0000000..6341d44
--- /dev/null
+++ b/src/ray.hpp
@@ -0,0 +1,15 @@
+#ifndef RAY_H
+#define RAY_H
+
+#include "vector.hpp"
+
+class Ray {
+ public:
+ Ray(Vec3d start, Vec3d direction, bool normalize);
+ Ray(Vec3d a, Vec3d b);
+
+ Vec3d m_start;
+ Vec3d m_direction;
+};
+
+#endif
diff --git a/src/scene.cpp b/src/scene.cpp
index d65dca7..d866fe4 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -1,5 +1,5 @@
#include "scene.hpp"
-void Scene::addObject(Object obj) {
- objs.push_back(obj);
+void Scene::addObject(Object &obj) {
+ objs.push_back(&obj);
}
diff --git a/src/scene.hpp b/src/scene.hpp
index 6e3f33e..a06ccb4 100644
--- a/src/scene.hpp
+++ b/src/scene.hpp
@@ -6,9 +6,9 @@
class Scene {
public:
- void addObject(Object obj);
+ void addObject(Object &obj);
- std::vector<Object> objs;
+ std::vector<Object*> objs;
};
diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
index 0000000..070f956
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,53 @@
+#include "vector.hpp"
+
+#include <math.h>
+
+Vec3d::Vec3d() {
+ set(0, 0, 0);
+}
+
+Vec3d::Vec3d(double x, double y, double z) {
+ set(x, y, z);
+}
+
+void Vec3d::set(double x, double y, double z) {
+ m_x = x;
+ m_y = y;
+ m_z = z;
+}
+
+void Vec3d::normalize() {
+ auto len = length();
+ if (len == 0) {
+ throw "Normalizing zero vector";
+ }
+
+ m_x /= len;
+ m_y /= len;
+ m_z /= len;
+}
+
+double Vec3d::length() const {
+ return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
+}
+
+double Vec3d::dot(const Vec3d &vec) const {
+ return m_x * vec.m_x + m_y * vec.m_y + m_z * vec.m_z;
+}
+
+Vec3d Vec3d::operator-(const Vec3d &vec) const {
+ return Vec3d(
+ m_x - vec.m_x,
+ m_y - vec.m_y,
+ m_z - vec.m_z
+ );
+}
+
+Vec3d Vec3d::operator-() const {
+ return Vec3d(
+ -m_x,
+ -m_y,
+ -m_z
+ );
+}
+
diff --git a/src/vector.hpp b/src/vector.hpp
index 6d15f34..76eb883 100644
--- a/src/vector.hpp
+++ b/src/vector.hpp
@@ -2,17 +2,23 @@
#define VECTOR_H
class Vec3d {
- Vec3d();
- Vec3d(double x, double y, double z);
+ public:
+ Vec3d();
+ Vec3d(double x, double y, double z);
- void set(double x, double y, double z);
- void normalize();
+ void set(double x, double y, double z);
+ void normalize();
- double length();
+ double length() const;
+ double dot(const Vec3d &vec) const;
- Vec3d cross(const Vec3d &vec);
+ Vec3d cross(const Vec3d &vec) const;
- // Operators
+ // Operators
+ Vec3d operator-(const Vec3d &vec) const;
+ Vec3d operator-() const;
+
+ double m_x, m_y, m_z;
};
#endif