From 8ee9e71a0a5de34ee7abe2f363638395dade9bf1 Mon Sep 17 00:00:00 2001 From: Ben Kyd Date: Mon, 5 Aug 2019 02:14:28 +0100 Subject: [PATCH] triangles --- src/definitions/primatives/primative.hpp | 11 ++++++ src/definitions/primatives/triangle.cpp | 45 ++++++++++++++++++++++++ src/definitions/primatives/triangle.hpp | 17 +++++++++ src/engine/progressiverenderer.cpp | 7 +++- src/inferno.hpp | 1 + test/main.cpp | 1 + 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/definitions/primatives/triangle.cpp create mode 100644 src/definitions/primatives/triangle.hpp diff --git a/src/definitions/primatives/primative.hpp b/src/definitions/primatives/primative.hpp index 16266b9..49586e9 100644 --- a/src/definitions/primatives/primative.hpp +++ b/src/definitions/primatives/primative.hpp @@ -20,6 +20,10 @@ public: float radius; // Plane glm::vec3 normal; + // Triangle + glm::vec3 points[3]; + glm::vec3 normals[3]; + PrimativeType type = TYPE_NONE; @@ -35,6 +39,13 @@ public: type = TYPE_PLANE; } + // Triangle constructor + Primative(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 n0, glm::vec3 n1, glm::vec3 n2) { + points[0] = p0; points[1] = p1; points[2] = p2; + normals[0] = n0; normals[1] = n1; normals[2] = n2; + type = TYPE_TRI; + } + virtual bool DoesIntersect(Ray& ray, float& t) = 0; virtual glm::vec3 SurfaceNormal(glm::vec3 hitPoint) = 0; virtual glm::vec2 TexCoords(glm::vec3 hitPoint) = 0; diff --git a/src/definitions/primatives/triangle.cpp b/src/definitions/primatives/triangle.cpp new file mode 100644 index 0000000..4005f1f --- /dev/null +++ b/src/definitions/primatives/triangle.cpp @@ -0,0 +1,45 @@ +#include "triangle.hpp" +#include "../ray.hpp" + +bool Triangle::DoesIntersect(Ray& ray, float& t) { + glm::vec3 vertex0 = points[0]; + glm::vec3 vertex1 = points[1]; + glm::vec3 vertex2 = points[2]; + glm::vec3 edge1, edge2, h, s, q; + float a,f,u,v; + edge1 = vertex1 - vertex0; + edge2 = vertex2 - vertex0; + h = glm::cross(ray.direction, edge2); + a = glm::dot(edge1, h); + if (a > -EPSILON && a < EPSILON) + return false; // This ray is parallel to this triangle. + f = 1.0/a; + s = ray.origin - vertex0; + u = f * glm::dot(s, h); + if (u < 0.0 || u > 1.0) + return false; + q = glm::cross(s, edge1); + v = f * glm::dot(ray.direction, q); + if (v < 0.0 || u + v > 1.0) + return false; + // At this stage we can compute t to find out where the intersection point is on the line. + t = f * glm::dot(edge2, q); + if (t > EPSILON) // ray intersection + return true; + else // This means that there is a line intersection but not a ray intersection. + return false; +} + +glm::vec3 Triangle::SurfaceNormal(glm::vec3 hitPoint) { + return ((normals[0] + normals[1] + normals[2]) / 3.0f); +} + +glm::vec2 Triangle::TexCoords(glm::vec3 hitPoint) { + return { 0.0f, 0.0f }; +} + +void Triangle::Translate(glm::vec3 trans) { + points[0] += trans; + points[1] += trans; + points[2] += trans; +} diff --git a/src/definitions/primatives/triangle.hpp b/src/definitions/primatives/triangle.hpp new file mode 100644 index 0000000..c9d9cb6 --- /dev/null +++ b/src/definitions/primatives/triangle.hpp @@ -0,0 +1,17 @@ +#ifndef INFERNO_DEFINITIONS_PRIMATIVES_TRIANGLE_H_ +#define INFERNO_DEFINITIONS_PRIMATIVES_TRIANGLE_H_ + +#include "primative.hpp" + +class Triangle : public Primative { +public: + Triangle(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 n0, glm::vec3 n1, glm::vec3 n2) + : Primative(p0, p1, p2, n0, n1, n2) { } + + bool DoesIntersect(Ray& ray, float& t) override; + glm::vec3 SurfaceNormal(glm::vec3 hitPoint) override; + glm::vec2 TexCoords(glm::vec3 hitPoint) override; + void Translate(glm::vec3 trans) override; +}; + +#endif diff --git a/src/engine/progressiverenderer.cpp b/src/engine/progressiverenderer.cpp index 61719d3..58eb582 100644 --- a/src/engine/progressiverenderer.cpp +++ b/src/engine/progressiverenderer.cpp @@ -26,6 +26,7 @@ void ProgressiveRenderer::Render() { while (SDL_PollEvent(&e)) if (e.type == SDL_QUIT) m_interface->Close(); + #pragma omp parallel for schedule(dynamic) for (int x = 0; x < m_scene->w; x++) for (int y = 0; y < m_scene->h; y++) { Ray ray = m_scene->camera->CastRay(x, y); @@ -36,13 +37,17 @@ void ProgressiveRenderer::Render() { if (smh->DoesIntersect(ray, t)) { if (smh->type == TYPE_SPHERE) { m_interface->SetPixelSafe(x, y, 0x00FF00); - } else { + } else if (smh->type == TYPE_PLANE) { m_interface->SetPixelSafe(x, y, 0x00FFFF); + } else { + m_interface->SetPixelSafe(x, y, 0xFF00FF); } } } } + m_scene->objects[1]->center.y += 0.01f; + // Swap framebuffers m_interface->Update(); } diff --git a/src/inferno.hpp b/src/inferno.hpp index 84db6bc..d56a877 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -12,6 +12,7 @@ #include "definitions/camera.hpp" #include "definitions/primatives/sphere.hpp" #include "definitions/primatives/plane.hpp" +#include "definitions/primatives/triangle.hpp" class Display; class Renderer; diff --git a/test/main.cpp b/test/main.cpp index 328c27f..90d8313 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -15,6 +15,7 @@ int main(int argc, char** argv) { scene->camera = new Camera(600, 600); scene->objects.push_back(new Plane({0.0f, -0.5f, 0.0f}, {0.0f, -1.0f, 0.0f})); scene->objects.push_back(new Sphere({0.0f, 0.0f, -4.0f}, 1.0f)); + scene->objects.push_back(new Triangle({ 0.0f, 0.0f, -1.0f }, { 1.0f, 1.0f, 0.0f }, { -1.0f, 1.0f, 0.0f }, { 1.0f, -1.0f ,0.0f }, { 0.25f, 0.75f, 0.75f }, { 0.0f, 0.0f, 0.0f })); inferno.SetScene(scene);