diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index a8490dd..65581a5 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:30:18 by ycontre #+# #+# */ -/* Updated: 2025/01/19 18:46:38 by ycontre ### ########.fr */ +/* Updated: 2025/01/22 19:20:09 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -96,6 +96,20 @@ struct GPUBvhData int triangle_start_index; }; +struct GPUTopBvh +{ + alignas(16) glm::vec3 min; + alignas(16) glm::vec3 max; + + int left_index; + int right_index; + + int is_leaf; + + int first_bvh_data; + int bvh_data_count; +}; + class Sphere; class Camera; @@ -120,6 +134,7 @@ class Scene std::vector &getMaterialData(); + std::vector &getTopBvh(); std::vector &getBvhData(); std::vector &getBvh(); @@ -130,6 +145,7 @@ class Scene GPUMaterial getMaterial(int material_index); private: + std::vector _gpu_top_bvh; std::vector _gpu_bvh_data; std::vector _gpu_bvh; diff --git a/includes/RT/TopBVH.hpp b/includes/RT/TopBVH.hpp index fe09d63..0afafbc 100644 --- a/includes/RT/TopBVH.hpp +++ b/includes/RT/TopBVH.hpp @@ -29,14 +29,16 @@ class TopBVH float evaluateSah(std::vector &bvhs_data, std::vector &bvhs, int axis, float pos); - // int getSize(); + int getSize(); // int getLeaves(); - // void flatten(std::vector &TopBVHs, int ¤tIndex); - // GPUTopBVH toGPUTopBVH(); + // void flatten(std::vector &TopBVHs, int ¤tIndex); + // GPUTopBvh toGPUTopBvh(); + std::vector getGPUTopBvhs(); + void flatten(std::vector &top_bvhs, int ¤tIndex); // const AABB &getAABB() const; - // std::vector getGPUTopBVHs(); + // std::vector getGPUTopBvhs(); private: diff --git a/shaders/debug.glsl b/shaders/debug.glsl index 6c8ddcc..f42b514 100644 --- a/shaders/debug.glsl +++ b/shaders/debug.glsl @@ -67,6 +67,24 @@ layout(std430, binding = 2) buffer TriangleBuffer GPUTriangle triangles[]; }; +struct GPUTopBvh +{ + vec3 min; + vec3 max; + + int left_index; + int right_index; + + int is_leaf; + + int first_bvh; + int bvh_count; +}; +layout(std430, binding = 3) buffer TopBvhBuffer +{ + GPUTopBvh TopBvh[]; +}; + struct GPUBvhData { mat4 transform; @@ -76,7 +94,7 @@ struct GPUBvhData int bvh_start_index; int triangle_start_index; }; -layout(std430, binding = 3) buffer BvhDataBuffer +layout(std430, binding = 4) buffer BvhDataBuffer { GPUBvhData BvhData[]; }; @@ -94,7 +112,7 @@ struct GPUBvh int first_primitive; int primitive_count; }; -layout(std430, binding = 4) buffer BvhBuffer +layout(std430, binding = 5) buffer BvhBuffer { GPUBvh Bvh[]; }; @@ -174,10 +192,12 @@ hitInfo traceBVH(Ray ray, GPUBvhData bvh_data, inout Stats stats) if (intersectTriangle(ray, obj, temp_hit) && temp_hit.t < hit.t) { hit.t = temp_hit.t; - hit.normal = temp_hit.normal; + hit.last_t = temp_hit.last_t; hit.obj_index = bvh_data.triangle_start_index + node.first_primitive + i; + hit.mat_index = obj.mat_index; + hit.position = temp_hit.position; + hit.normal = temp_hit.normal; } - stats.triangle_count++; } } else @@ -191,10 +211,8 @@ hitInfo traceBVH(Ray ray, GPUBvhData bvh_data, inout Stats stats) left_hit.t = 1e30; right_hit.t = 1e30; - stats.box_count += 2; - - bool left_bool = intersectRayBVH(ray, left_node, left_hit); - bool right_bool = intersectRayBVH(ray, right_node, right_hit); + bool left_bool = intersectRayBVH(ray, left_node.min, left_node.max, left_hit); + bool right_bool = intersectRayBVH(ray, right_node.min, left_node.max, right_hit); if (left_hit.t > right_hit.t) { @@ -212,37 +230,102 @@ hitInfo traceBVH(Ray ray, GPUBvhData bvh_data, inout Stats stats) return (hit); } -hitInfo traverseBVHs(Ray ray, inout Stats stats) + +hitInfo traverseBVHs(Ray ray, GPUBvhData bvh_data, inout Stats stats) { - hitInfo hit; - + hitInfo hit; + hit.t = 1e30; hit.obj_index = -1; - for (int i = 0; i < u_bvhNum; i++) - { - GPUBvhData bvh_data = BvhData[i]; - - mat3 transformMatrix = mat3(bvh_data.transform); - mat3 inverseTransformMatrix = inverse(transformMatrix); + mat3 transformMatrix = mat3(bvh_data.transform); + mat3 inverseTransformMatrix = inverse(transformMatrix); - Ray transformedRay; - transformedRay.direction = normalize(transformMatrix * ray.direction); - transformedRay.origin = transformMatrix * (ray.origin - bvh_data.offset); - transformedRay.inv_direction = (1. / transformedRay.direction); - - hitInfo temp_hit = traceBVH(transformedRay, BvhData[i], stats); + Ray transformedRay; + transformedRay.direction = normalize(transformMatrix * ray.direction); + transformedRay.origin = transformMatrix * (ray.origin - bvh_data.offset); + transformedRay.inv_direction = (1. / transformedRay.direction); + + hit = traceBVH(transformedRay, bvh_data, stats); - temp_hit.t = temp_hit.t / bvh_data.scale; - - if (temp_hit.t < hit.t) + if (hit.obj_index == -1) + return (hit); + + hit.t = hit.t / bvh_data.scale; + hit.last_t = hit.last_t / bvh_data.scale; + hit.obj_index = hit.obj_index; + hit.mat_index = hit.mat_index; + hit.position = inverseTransformMatrix * hit.position + bvh_data.offset; + hit.normal = normalize(inverseTransformMatrix * hit.normal); + + return (hit); +} + +hitInfo traceTopBVH(Ray ray, inout Stats stats) +{ + hitInfo hit; + hitInfo hit_bvh; + + hit.t = 1e30; + hit.obj_index = -1; + + int stack[32]; + int stack_ptr = 0; + stack[0] = 0; + + while (stack_ptr >= 0) + { + int current_index = stack[stack_ptr--]; + GPUTopBvh node = TopBvh[current_index]; + + + if (node.is_leaf != 0) { - hit.t = temp_hit.t; - hit.obj_index = temp_hit.obj_index; - hit.normal = normalize(inverseTransformMatrix * temp_hit.normal); + for (int i = 0; i < node.bvh_count; i++) + { + GPUBvhData bvh_data = BvhData[node.first_bvh + i]; + + hitInfo temp_hit = traverseBVHs(ray, bvh_data, stats); + if (temp_hit.obj_index != -1 && temp_hit.t < hit.t) + { + hit.t = temp_hit.t; + hit.last_t = temp_hit.last_t; + hit.obj_index = temp_hit.obj_index; + hit.mat_index = temp_hit.mat_index; + hit.position = temp_hit.position; + hit.normal = temp_hit.normal; + } + } } - } + else + { + GPUTopBvh left_node = TopBvh[node.left_index]; + GPUTopBvh right_node = TopBvh[node.right_index]; + hitInfo left_hit; + hitInfo right_hit; + + left_hit.t = 1e30; + right_hit.t = 1e30; + + stats.box_count += 2; + + bool left_bool = intersectRayBVH(ray, left_node.min, left_node.max, left_hit); + bool right_bool = intersectRayBVH(ray, right_node.min, right_node.max, right_hit); + + if (left_hit.t > right_hit.t) + { + if (left_hit.t < hit.t && left_bool) stack[++stack_ptr] = node.left_index; + if (right_hit.t < hit.t && right_bool) stack[++stack_ptr] = node.right_index; + } + else + { + if (right_hit.t < hit.t && right_bool) stack[++stack_ptr] = node.right_index; + if (left_hit.t < hit.t && left_bool) stack[++stack_ptr] = node.left_index; + } + } + } + return (hit); } @@ -263,7 +346,7 @@ vec3 debugColor(vec2 uv) Ray ray = initRay(uv); Stats stats = Stats(0, 0); - hitInfo hit = traverseBVHs(ray, stats); + hitInfo hit = traceTopBVH(ray, stats); float box_display = float(stats.box_count) / float(debug.box_treshold); float triangle_display = float(stats.triangle_count) / float(debug.triangle_treshold); diff --git a/shaders/intersect.glsl b/shaders/intersect.glsl index 255382a..23ad501 100644 --- a/shaders/intersect.glsl +++ b/shaders/intersect.glsl @@ -225,12 +225,12 @@ bool intersect(Ray ray, GPUObject obj, out hitInfo hit) } -bool intersectRayBVH(Ray ray, GPUBvh node, inout hitInfo hit) +bool intersectRayBVH(Ray ray, vec3 min_pos, vec3 max_pos, inout hitInfo hit) { // vec3 inv_direction = 1.0 / ray.direction; - vec3 t1 = (node.min - ray.origin) * ray.inv_direction; - vec3 t2 = (node.max - ray.origin) * ray.inv_direction; + vec3 t1 = (min_pos - ray.origin) * ray.inv_direction; + vec3 t2 = (max_pos - ray.origin) * ray.inv_direction; vec3 tMin = min(t1, t2); vec3 tMax = max(t1, t2); diff --git a/shaders/trace.glsl b/shaders/trace.glsl index 9356c77..6d2463f 100644 --- a/shaders/trace.glsl +++ b/shaders/trace.glsl @@ -99,8 +99,8 @@ hitInfo traceBVH(Ray ray, GPUBvhData bvh_data) left_hit.t = 1e30; right_hit.t = 1e30; - bool left_bool = intersectRayBVH(ray, left_node, left_hit); - bool right_bool = intersectRayBVH(ray, right_node, right_hit); + bool left_bool = intersectRayBVH(ray, left_node.min, left_node.max, left_hit); + bool right_bool = intersectRayBVH(ray, right_node.min, left_node.max, right_hit); if (left_hit.t > right_hit.t) { @@ -118,70 +118,97 @@ hitInfo traceBVH(Ray ray, GPUBvhData bvh_data) return (hit); } -// hitInfo traverseBVHs(Ray ray) -// { -// hitInfo hit; - -// hit.t = 1e30; -// hit.obj_index = -1; -// for (int i = 0; i < u_bvhNum; i++) -// { -// GPUBvhData bvh_data = BvhData[i]; - -// ray.origin -= bvh_data.offset; -// hitInfo temp_hit = traceBVH(ray, bvh_data); - -// if (temp_hit.t < hit.t) -// { -// hit.t = temp_hit.t; -// hit.last_t = temp_hit.last_t; -// hit.obj_index = temp_hit.obj_index; -// hit.mat_index = temp_hit.mat_index; -// hit.position = temp_hit.position; -// hit.normal = temp_hit.normal; -// } - -// ray.origin += bvh_data.offset; -// } - -// return (hit); -// } - -hitInfo traverseBVHs(Ray ray) +hitInfo traverseBVHs(Ray ray, GPUBvhData bvh_data) { - hitInfo hit; - hit.t = 1e30; hit.obj_index = -1; - for (int i = 0; i < u_bvhNum; i++) - { - GPUBvhData bvh_data = BvhData[i]; - - mat3 transformMatrix = mat3(bvh_data.transform); - mat3 inverseTransformMatrix = inverse(transformMatrix); + mat3 transformMatrix = mat3(bvh_data.transform); + mat3 inverseTransformMatrix = inverse(transformMatrix); - Ray transformedRay; - transformedRay.direction = normalize(transformMatrix * ray.direction); - transformedRay.origin = transformMatrix * (ray.origin - bvh_data.offset); - transformedRay.inv_direction = (1. / transformedRay.direction); - - hitInfo temp_hit = traceBVH(transformedRay, BvhData[i]); + Ray transformedRay; + transformedRay.direction = normalize(transformMatrix * ray.direction); + transformedRay.origin = transformMatrix * (ray.origin - bvh_data.offset); + transformedRay.inv_direction = (1. / transformedRay.direction); + + hit = traceBVH(transformedRay, BvhData[i]); - temp_hit.t = temp_hit.t / bvh_data.scale; + if (hit.obj_index == -1) + return (hit); - if (temp_hit.t < hit.t) + hit.t = hit.t / bvh_data.scale; + hit.last_t = hit.last_t / bvh_data.scale; + hit.obj_index = hit.obj_index; + hit.mat_index = hit.mat_index; + hit.position = inverseTransformMatrix * hit.position + bvh_data.offset; + hit.normal = normalize(inverseTransformMatrix * hit.normal); + + return (hit); +} + +hitInfo traceTopBVH(Ray ray) +{ + hitInfo hit; + hitInfo hit_bvh; + + hit.t = 1e30; + hit.obj_index = -1; + + int stack[32]; + int stack_ptr = 0; + stack[0] = 0; + + while (stack_ptr >= 0) + { + int current_index = stack[stack_ptr--]; + GPUTopBvh node = TopBvh[current_index]; + + if (node.is_leaf != 0) { - hit.t = temp_hit.t; - hit.last_t = temp_hit.last_t / bvh_data.scale; - hit.obj_index = temp_hit.obj_index; - hit.mat_index = temp_hit.mat_index; - hit.position = inverseTransformMatrix * temp_hit.position + bvh_data.offset; - hit.normal = normalize(inverseTransformMatrix * temp_hit.normal); + for (int i = 0; i < node.bvh_count; i++) + { + GPUBvhData bvh_data = bvh_data[node.first_bvh + i]; + + hitInfo temp_hit = traverseBVHs(ray, bvh_data); + if (temp_hit.obj_index != -1 && temp_hit.t < hit.t) + { + hit.t = temp_hit.t; + hit.last_t = temp_hit.last_t; + hit.obj_index = bvh_data.triangle_start_index + node.first_primitive + i; + hit.mat_index = obj.mat_index; + hit.position = temp_hit.position; + hit.normal = temp_hit.normal; + } + } } - } + else + { + GPUTopBvh left_node = TopBvh[node.left_index]; + GPUTopBvh right_node = TopBvh[node.right_index]; + hitInfo left_hit; + hitInfo right_hit; + + left_hit.t = 1e30; + right_hit.t = 1e30; + + bool left_bool = intersectRayBVH(ray, left_node.min, left_node.max, left_hit); + bool right_bool = intersectRayBVH(ray, right_node.min, left_mode.max, right_hit); + + if (left_hit.t > right_hit.t) + { + if (left_hit.t < hit.t && left_bool) stack[++stack_ptr] = node.left_index; + if (right_hit.t < hit.t && right_bool) stack[++stack_ptr] = node.right_index; + } + else + { + if (right_hit.t < hit.t && right_bool) stack[++stack_ptr] = node.right_index; + if (left_hit.t < hit.t && left_bool) stack[++stack_ptr] = node.left_index; + } + } + } + return (hit); } @@ -193,7 +220,7 @@ hitInfo traceRay(Ray ray) for (int i = 0; i < 10; i++) // portal ray { - hitBVH = traverseBVHs(ray); + hitBVH = traceTopBVH(ray); hitScene = traceScene(ray); hit = hitBVH.t < hitScene.t ? hitBVH : hitScene; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index cda5306..69a8fdf 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/01/20 18:55:25 by ycontre ### ########.fr */ +/* Updated: 2025/01/22 18:45:48 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,6 +30,7 @@ int main(int argc, char **argv) const std::vector &triangle_data = scene.getTriangleData(); const std::vector &bvh_nodes = scene.getBvh(); const std::vector &bvh_data = scene.getBvhData(); + const std::vector &top_bvh = scene.getTopBvh(); const std::vector &material_data = scene.getMaterialData(); std::cout << "Sending " << object_data.size() << " objects for " << \ @@ -51,29 +52,35 @@ int main(int argc, char **argv) glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUTriangle) * triangle_data.size(), triangle_data.data(), GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, trianglesSSBO); - GLuint bvh_nodesSSBO; - glGenBuffers(1, &bvh_nodesSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvh_nodesSSBO); + GLuint top_bvhSSBO; + glGenBuffers(1, &top_bvhSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, top_bvhSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUTopBvh) * top_bvh.size(), top_bvh.data(), GL_STATIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, top_bvhSSBO); + + GLuint bvh_dataSSBO; + glGenBuffers(1, &bvh_dataSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvh_dataSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUBvhData) * bvh_data.size(), bvh_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, bvh_nodesSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, bvh_dataSSBO); GLuint bvhSSBO; glGenBuffers(1, &bvhSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvhSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUBvh) * bvh_nodes.size(), bvh_nodes.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, bvhSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, bvhSSBO); GLuint materialSSBO; glGenBuffers(1, &materialSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUMaterial) * material_data.size(), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, materialSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, materialSSBO); GLuint lightSSBO; glGenBuffers(1, &lightSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, scene.getGPULights().size() * sizeof(int), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, lightSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, lightSSBO); GLuint cameraUBO; diff --git a/srcs/class/BVH.cpp b/srcs/class/BVH.cpp index 496dc40..c39c9a7 100644 --- a/srcs/class/BVH.cpp +++ b/srcs/class/BVH.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/16 21:48:48 by TheRed #+# #+# */ -/* Updated: 2025/01/19 18:30:27 by ycontre ### ########.fr */ +/* Updated: 2025/01/22 19:23:38 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index d7a378b..25e8102 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:29:41 by ycontre #+# #+# */ -/* Updated: 2025/01/21 14:45:04 by tomoron ### ########.fr */ +/* Updated: 2025/01/22 19:17:21 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,7 +59,7 @@ bool Scene::parseScene(char *name) file.close(); TopBVH *top_bvh = new TopBVH(_gpu_bvh_data, _gpu_bvh, 0, _gpu_bvh_data.size()); - (void) top_bvh; + _gpu_top_bvh = top_bvh->getGPUTopBvhs(); std::cout << "Parsing done" << std::endl; @@ -252,7 +252,12 @@ GPUDebug &Scene::getDebug() return (_gpu_debug); } -std::vector &Scene::getBvhData() +std::vector &Scene::getTopBvh() +{ + return (_gpu_top_bvh); +} + +std::vector &Scene::getBvhData() { return (_gpu_bvh_data); } diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index 26afc05..ce82d5f 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/26 21:43:51 by TheRed #+# #+# */ -/* Updated: 2025/01/21 15:57:42 by tomoron ### ########.fr */ +/* Updated: 2025/01/22 17:50:36 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/class/TopBVH.cpp b/srcs/class/TopBVH.cpp index 2a05fba..8c8b1d7 100644 --- a/srcs/class/TopBVH.cpp +++ b/srcs/class/TopBVH.cpp @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* TopBvh.cpp :+: :+: :+: */ +/* TopBVH.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: TheRed +#+ +:+ +#+ */ +/* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/21 21:46:45 by TheRed #+# #+# */ -/* Updated: 2025/01/21 21:46:45 by TheRed ### ########.fr */ +/* Updated: 2025/01/22 19:32:43 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -54,8 +54,8 @@ float TopBVH::evaluateSah(std::vector &bvhs_data, std::vector &bvhs_data, std::vector & { GPUBvhData bvh_data = bvhs_data[i]; GPUBvh root = bvhs[bvh_data.bvh_start_index]; - glm::vec3 min = root.min - bvh_data.offset; - glm::vec3 max = root.max - bvh_data.offset; + glm::vec3 min = root.min + bvh_data.offset; + glm::vec3 max = root.max + bvh_data.offset; glm::vec3 centroid = (min + max) * 0.5f; if (centroid[axis] < split_pos) @@ -141,4 +141,54 @@ void TopBVH::subdivide(std::vector &bvhs_data, std::vector & _right = new TopBVH(bvhs_data, bvhs, i, _bvh_count - left_count); _bvh_count = 0; +} + +int TopBVH::getSize() +{ + int count = 0; + + if (_is_leaf) + return (0); + + count += 1 + _left->getSize(); + count += 1 + _right->getSize(); + + return (count); +} + +void TopBVH::flatten(std::vector &top_bvhs, int ¤tIndex) +{ + GPUTopBvh self_top_bvh; + + self_top_bvh.is_leaf = _is_leaf; + self_top_bvh.first_bvh_data = _first_bvh; + self_top_bvh.bvh_data_count = _bvh_count; + self_top_bvh.max = _aabb.max; + self_top_bvh.min = _aabb.min; + + int self_index = currentIndex++; + + self_top_bvh.left_index = -1; + self_top_bvh.right_index = -1; + + if (!_is_leaf) + { + self_top_bvh.left_index = currentIndex; + _left->flatten(top_bvhs, currentIndex); + + self_top_bvh.right_index = currentIndex; + _right->flatten(top_bvhs, currentIndex); + } + + top_bvhs[self_index] = self_top_bvh; +} + +std::vector TopBVH::getGPUTopBvhs() +{ + std::vector bvhs(getSize() + 1); + + int currentIndex = 0; + flatten(bvhs, currentIndex); + + return (bvhs); } \ No newline at end of file