diff --git a/Makefile b/Makefile index 3344893..1096c76 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,8 @@ ALL_SRCS := $(IMGUI_SRCS) \ class/Camera.cpp \ class/Scene.cpp \ class/SceneParser.cpp \ - class/ObjParser.cpp + class/ObjParser.cpp \ + CLASS/BVH.cpp \ SRCS := $(ALL_SRCS:%=$(SRCS_DIR)/%) OBJS := $(addprefix $(OBJS_DIR)/, $(SRCS:%.cpp=%.o)) diff --git a/RT b/RT new file mode 100644 index 0000000..a06a478 Binary files /dev/null and b/RT differ diff --git a/imgui.ini b/imgui.ini index c229286..85e92ba 100644 --- a/imgui.ini +++ b/imgui.ini @@ -7,7 +7,7 @@ Pos=1655,22 Size=229,184 [Window][Material] -Pos=1648,220 +Pos=1629,224 Size=266,285 [Window][Fog settings] diff --git a/includes/RT.hpp b/includes/RT.hpp index 3c6a1a3..f779482 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -61,6 +61,7 @@ struct Vertex { # include "Scene.hpp" # include "SceneParser.hpp" # include "ObjParser.hpp" +# include "BVH.hpp" diff --git a/includes/RT/BVH.hpp b/includes/RT/BVH.hpp new file mode 100644 index 0000000..0d5e34f --- /dev/null +++ b/includes/RT/BVH.hpp @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* BVH.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/16 21:36:19 by TheRed #+# #+# */ +/* Updated: 2025/01/16 21:36:19 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef RT_BVH__HPP +# define RT_BVH__HPP + +# include "RT.hpp" + +struct AABB +{ + glm::vec3 min; + glm::vec3 max; + + AABB(glm::vec3 min, glm::vec3 max) : min(min), max(max) {} +}; + +struct GPUObject; + +class BVH +{ + public: + BVH(std::vector primitives, int first_primitive, int primitive_count); + + + void showAABB(Scene *scene); + + void updateBounds(std::vector primitives); + void subdivide(std::vector primitives); + + const AABB &getAABB() const; + + + private: + AABB _aabb; + + BVH *_left; + BVH *_right; + + bool _is_leaf; + + int _first_primitive; + int _primitive_count; +}; + +#endif \ No newline at end of file diff --git a/scenes/test.rt b/scenes/test.rt index 091497c..674db03 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -11,8 +11,6 @@ MAT 255 255 255 5.0 0.0 0.0 //light MAT 255 255 255 0.0 0.0 0.0 TRN // glass -sp -5 2 0 2 6 -# qu -5 0 0 0 2 0 0 0 2 6 sp 0 -25 0 50 4 @@ -22,7 +20,7 @@ sp -2.2 0.4 0.25 1 2 sp -3 0.2 0.50 0.75 3 sp -3.8 -0.1 0.60 0.5 5 -sp 0 1 5 1 7 +sp -0.071350 13.247917 0.518550 2 5 cy 0 1 2 0.5 2 -1.5 0 0.75 1 diff --git a/srcs/class/BVH.cpp b/srcs/class/BVH.cpp new file mode 100644 index 0000000..99d4c84 --- /dev/null +++ b/srcs/class/BVH.cpp @@ -0,0 +1,127 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* BVH.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/16 21:48:48 by TheRed #+# #+# */ +/* Updated: 2025/01/16 21:48:48 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "BVH.hpp" + +BVH::BVH(std::vector primitives, int first_primitive, int primitive_count) : _aabb(AABB(glm::vec3(1e30f), glm::vec3(-1e30f))) +{ + _left = nullptr; + _right = nullptr; + + _is_leaf = true; + + _first_primitive = first_primitive; + _primitive_count = primitive_count; + + updateBounds(primitives); + subdivide(primitives); +} + +void BVH::updateBounds(std::vector primitives) +{ + for (int i = 0; i < _primitive_count; i++) + { + GPUObject leaf_triangle = primitives[_first_primitive + i]; + + if (leaf_triangle.type != (int)Object::Type::TRIANGLE) + continue ; + + if (leaf_triangle.type == (int)Object::Type::TRIANGLE) + { + leaf_triangle.vertex1 += leaf_triangle.position; + leaf_triangle.vertex2 += leaf_triangle.position; + } + + _aabb.min = glm::min(_aabb.min, leaf_triangle.position); + _aabb.min = glm::min(_aabb.min, leaf_triangle.vertex1); + _aabb.min = glm::min(_aabb.min, leaf_triangle.vertex2); + _aabb.max = glm::max(_aabb.max, leaf_triangle.position); + _aabb.max = glm::max(_aabb.max, leaf_triangle.vertex1); + _aabb.max = glm::max(_aabb.max, leaf_triangle.vertex2); + } +} + +void BVH::subdivide(std::vector primitives) +{ + if (_primitive_count <= 2) + return ; + + std::cout << "subdivide" << std::endl; + + glm::vec3 extent = _aabb.max - _aabb.min; + + int axis = 0; + if (extent.y > extent.x) axis = 1; + if (extent.z > extent[axis]) axis = 2; + + glm::vec3 split_pos = _aabb.min + extent[axis] * 0.5f; + + int i = _first_primitive; + int j = _first_primitive + _primitive_count - 1; + + while (i <= j) + { + glm::vec3 centroid = primitives[i].position + primitives[i].vertex1 + primitives[i].vertex2; + centroid /= 3.0f; + + if (centroid[axis] < split_pos[axis]) + i++; + else + { + std::swap(primitives[i], primitives[j]); + j--; + } + } + + int left_count = i - _first_primitive; + + std::cout << "left bvh starts from " << _first_primitive << " and has " << left_count << " primitives" << std::endl; + std::cout << "right bvh starts from " << i << " and has " << _primitive_count - left_count << " primitives" << std::endl; + + if (left_count == 0 || left_count == _primitive_count) + return ; + + + _is_leaf = false; + + _left = new BVH(primitives, _first_primitive, left_count); + _right = new BVH(primitives, i, _primitive_count - left_count); + + _primitive_count = 0; +} + +void BVH::showAABB(Scene *scene) +{ + if (_is_leaf) + { + + scene->addObject(new Sphere(_aabb.min, 0.5f, 6)); + scene->addObject(new Sphere(_aabb.max, 0.5f, 6)); + scene->addObject(new Sphere(glm::vec3(_aabb.min.x, _aabb.min.y, _aabb.max.z), 0.5f, 6)); + scene->addObject(new Sphere(glm::vec3(_aabb.min.x, _aabb.max.y, _aabb.min.z), 0.5f, 6)); + scene->addObject(new Sphere(glm::vec3(_aabb.max.x, _aabb.min.y, _aabb.min.z), 0.5f, 6)); + scene->addObject(new Sphere(glm::vec3(_aabb.min.x, _aabb.max.y, _aabb.max.z), 0.5f, 6)); + scene->addObject(new Sphere(glm::vec3(_aabb.max.x, _aabb.min.y, _aabb.max.z), 0.5f, 6)); + scene->addObject(new Sphere(glm::vec3(_aabb.max.x, _aabb.max.y, _aabb.min.z), 0.5f, 6)); + + } + else + { + _left->showAABB(scene); + _right->showAABB(scene); + } +} + +const AABB &BVH::getAABB() const +{ + return (_aabb); +} \ No newline at end of file diff --git a/srcs/class/ObjParser.cpp b/srcs/class/ObjParser.cpp index d83055f..fb3a378 100644 --- a/srcs/class/ObjParser.cpp +++ b/srcs/class/ObjParser.cpp @@ -61,20 +61,20 @@ void ObjParser::addTriangleFromPolygon(std::vector &vertices, Scene & v4 = vertices[(i + 2) % vertices.size()]; normal = glm::normalize(glm::cross(v2 - v1, v3 - v1)); - std::cout << glm::to_string(normal) << std::endl; + // std::cout << glm::to_string(normal) << std::endl; - float dot = glm::dot(normal, v4 - v1); - std::cout << dot << std::endl; + // float dot = glm::dot(normal, v4 - v1); + // std::cout << dot << std::endl; //if(isEar(v1, v2 ,v3, vertices)) //{ // vertices.erase(vertices.begin() + i); // scene.addObject(new Triangle(v1, v2 ,v3)); //} } - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; + // std::cout << std::endl; + // std::cout << std::endl; + // std::cout << std::endl; + // std::cout << std::endl; } void ObjParser::addFace(std::stringstream &line, std::vector &vertices, int mat, Scene &scene) @@ -89,9 +89,9 @@ void ObjParser::addFace(std::stringstream &line, std::vector &vertice if(face_vertices.size() < 3) throw std::runtime_error("OBJ : face does not have enough vertices"); - for(size_t i = 0; i < face_vertices.size(); i++) - std::cout << face_vertices[i].x << " " << face_vertices[i].y << " " << face_vertices[i].z << " | "; - std::cout << std::endl; + // for(size_t i = 0; i < face_vertices.size(); i++) + // std::cout << face_vertices[i].x << " " << face_vertices[i].y << " " << face_vertices[i].z << " | "; + // std::cout << std::endl; // while(face_vertices.size() > 3) // addTriangleFromPolygon(face_vertices, scene); diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index eafb359..205808e 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -52,6 +52,13 @@ bool Scene::parseScene(char *name) } } file.close(); + + //bvh + BVH *bvh = new BVH(_gpu_objects, 0, _gpu_objects.size()); + bvh->showAABB(this); + // addObject(new Cube((bvh->getAABB().max + bvh->getAABB().min) / 2.0f, bvh->getAABB().max - bvh->getAABB().min, 7)); + // + return (true); } diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index fdd2c45..1ed80a9 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -67,7 +67,7 @@ Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string com const char *fragmentCode = loadFileWithIncludes(fragmentPath); const char *computeCode = loadFileWithIncludes(computePath); - printWithLineNumbers(computeCode); + // printWithLineNumbers(computeCode); _vertex = glCreateShader(GL_VERTEX_SHADER);