aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2021-05-23 13:32:02 +0200
committerladevieq <ladevie.quentin@gmail.com>2021-05-23 13:32:02 +0200
commit2c07c0b7df2b13cd5deea8233e1c4eb61a85a766 (patch)
tree2133f08ab5ec84ee8013b43fd288120e1eaf85b7
parentb715df2c21dbb8656fc01d5a64605ac18cb5c6e4 (diff)
Naive BVH working + camera simple camera rotation
-rw-r--r--include/bvh-node.hpp86
-rw-r--r--include/camera.hpp4
-rw-r--r--src/camera.cpp20
-rw-r--r--src/main.cpp10
4 files changed, 88 insertions, 32 deletions
diff --git a/include/bvh-node.hpp b/include/bvh-node.hpp
index ee5068b..3a4ac4b 100644
--- a/include/bvh-node.hpp
+++ b/include/bvh-node.hpp
@@ -52,9 +52,8 @@ class bvh_node {
class bvh {
public:
- // TODO: Fix one level too deep BVH
void build(sphere* spheres, uint32_t spheres_count) {
- nodes = std::vector<bvh_node>(spheres_count * spheres_count);
+ nodes = std::vector<bvh_node>(2 * spheres_count - 1);
boxes = std::vector<aabb>(spheres_count);
for (uint32_t sphere_id = 0; sphere_id < spheres_count; sphere_id++) {
@@ -73,31 +72,49 @@ public:
void exporter() {
std::cout << "digraph bvh {" << std::endl;
- std::cout << "\t r";
- preorder(nodes[0].left_id, nodes[0].sphere_id);
+ std::cout << "\t 0";
+ // preorder(nodes[0].left_id, nodes[0].sphere_id);
+ traverse(nodes[0].left_id);
- std::cout << "\t r";
- preorder(nodes[0].left_id + 1, nodes[0].sphere_id);
+ std::cout << "\t 0";
+ // preorder(nodes[0].left_id + 1, nodes[0].sphere_id);
+ traverse(nodes[0].left_id + 1);
std::cout << "}" << std::endl;
}
- void preorder(int32_t id, int32_t sphere_id) {
+ bool traverse(int32_t id) {
if (id <= 0) {
- if (sphere_id < 0) {
- std::cout << ";" << std::endl;
- } else {
- std::cout << " -> sphere_" << sphere_id << ";" << std::endl;
- }
- return;
+ std::cout << ";" << std::endl;
+ return false;
}
std::cout << " -> " << id;
- preorder(nodes[id].left_id, nodes[id].sphere_id);
+ if (traverse(nodes[id].left_id)) {
+ std::cout << "\t " << id;
+ traverse(nodes[id].left_id + 1);
+ }
+
+ return true;
+ }
+
+ void preorder(int32_t id, int32_t sphere_id) {
+ if (id <= 0) {
+ return;
+ }
if (nodes[id].left_id > -1) {
+ std::cout << " -> " << id;
+ preorder(nodes[id].left_id, nodes[id].sphere_id);
+
std::cout << "\t " << id;
- preorder(nodes[id].left_id + 1, nodes[id].sphere_id);
+ if (nodes[nodes[id].left_id + 1].sphere_id == -1) {
+ preorder(nodes[id].left_id + 1, nodes[id].sphere_id);
+ } else {
+ std::cout << " -> sphere_" << nodes[nodes[id].left_id + 1].sphere_id << ";" << std::endl;
+ }
+ } else if (nodes[id].sphere_id > -1) {
+ std::cout << " -> sphere_" << nodes[id].sphere_id << ";" << std::endl;
}
}
@@ -114,35 +131,44 @@ private:
}
void subdivide(uint32_t parent_id, uint32_t begin, uint32_t end) {
- if ((end - begin) == 0) {
- return;
- }
-
- auto left_id = parent_id * 2 + 1;
- auto right_id = parent_id * 2 + 2;
+ if ((end - begin) == 2) {
+ auto left_id = ++next_node_id;
+ auto right_id = ++next_node_id;
- nodes[parent_id].left_id = left_id;
+ nodes[parent_id].left_id = left_id;
- nodes[left_id] = bvh_node();
- nodes[right_id] = bvh_node();
+ nodes[left_id] = bvh_node();
+ nodes[right_id] = bvh_node();
- nodes[left_id].bounding_box = compute_bounds(begin, begin + ((end - begin) / 2));
- nodes[right_id].bounding_box = compute_bounds(begin + ((end - begin) / 2), end);
+ nodes[left_id].bounding_box = boxes[begin];
+ nodes[right_id].bounding_box = boxes[begin + 1];
- if ((end - begin) == 2) {
nodes[left_id].sphere_id = begin;
nodes[right_id].sphere_id = begin + 1;
} else if ((end - begin) == 1) {
- nodes[left_id].sphere_id = begin;
+ nodes[parent_id].bounding_box = boxes[begin];
+ nodes[parent_id].sphere_id = begin;
} else {
- subdivide(left_id, begin, begin + ((end - begin) / 2));
- subdivide(right_id, begin + ((end - begin) / 2), end);
+ auto left_id = ++next_node_id;
+ auto right_id = ++next_node_id;
+
+ nodes[parent_id].left_id = left_id;
+
+ nodes[left_id] = bvh_node();
+ nodes[right_id] = bvh_node();
+
+ nodes[left_id].bounding_box = compute_bounds(begin, begin + ((end - begin) / 2) + 1);
+ nodes[right_id].bounding_box = compute_bounds(begin + ((end - begin) / 2) + 1, end);
+
+ subdivide(left_id, begin, begin + ((end - begin) / 2) + 1);
+ subdivide(right_id, begin + ((end - begin) / 2) + 1, end);
}
}
public:
std::vector<bvh_node> nodes;
std::vector<aabb> boxes;
+ uint32_t next_node_id = 0;
};
#endif // !__BVH_NODE_HPP_
diff --git a/include/camera.hpp b/include/camera.hpp
index 6adac87..60ca5b5 100644
--- a/include/camera.hpp
+++ b/include/camera.hpp
@@ -18,6 +18,8 @@ class camera {
void move(vec3 v);
+ void rotate_y(float theta);
+
point3 position;
@@ -33,7 +35,7 @@ class camera {
float lens_radius;
float fov;
float focus_distance;
- float padding;
+ float aspect_ratio;
};
#endif // !__CAMERA_HPP_
diff --git a/src/camera.cpp b/src/camera.cpp
index ff09e20..917cb4e 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -10,7 +10,7 @@ camera::camera(
float aspect_ratio,
float aperture,
float focus_dist
- ) : position(position), lens_radius(aperture / 2.0), fov(v_fov), focus_distance(focus_dist) {
+ ) : position(position), lens_radius(aperture / 2.0), fov(v_fov), focus_distance(focus_dist), aspect_ratio(aspect_ratio) {
forward = (target - position).unit();
right = forward.cross(vec3{ 0.0, 1.0, 0.0 }).unit();
@@ -27,6 +27,8 @@ camera::camera(
}
void camera::set_aspect_ratio(float aspect_ratio) {
+ aspect_ratio = aspect_ratio;
+
auto h = tan(deg_to_rad(fov) / 2.0);
auto viewport_height = 2.0 * h;
auto viewport_width = viewport_height * aspect_ratio;
@@ -41,3 +43,19 @@ void camera::move(vec3 v) {
position += v;
first_pixel = position - horizontal / 2.0 - vertical / 2.0 + focus_distance * forward;
}
+
+void camera::rotate_y(float theta) {
+ forward.x = forward.x * cos(theta) - forward.z * sin(theta);
+ forward.z = forward.x * sin(theta) + forward.z * cos(theta);
+
+ right = forward.cross(vec3{ 0.0, 1.0, 0.0 }).unit();
+ up = right.cross(forward).unit();
+
+ auto h = tan(deg_to_rad(fov) / 2.0);
+ auto viewport_height = 2.0 * h;
+ auto viewport_width = viewport_height * aspect_ratio;
+
+ horizontal = focus_distance * viewport_width * right;
+ vertical = focus_distance * viewport_height * up;
+ first_pixel = position - horizontal / 2.0 - vertical / 2.0 + focus_distance * forward;
+}
diff --git a/src/main.cpp b/src/main.cpp
index 19b7b54..f8699af 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -126,6 +126,16 @@ int main() {
move_vec = -((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.right.unit() * move_speed;
break;
}
+ case KEYS::E: {
+ ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.rotate_y(0.001f * delta_time);
+ reset_accumulation = true;
+ break;
+ }
+ case KEYS::Q: {
+ ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.rotate_y(-0.001f * delta_time);
+ reset_accumulation = true;
+ break;
+ }
case KEYS::SPACE: {
move_vec = ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.up.unit() * move_speed;
break;