From 41ea86d3ec26b4268cf1652aa73040e4a4d60918 Mon Sep 17 00:00:00 2001 From: NADAL Jean-Baptiste Date: Tue, 5 Mar 2024 17:01:38 +0100 Subject: [PATCH] [WIP] Add reflective parameter into material --- .clang-format | 1 + apps/chapter_05.cpp | 8 ++--- apps/chapter_06.cpp | 16 ++++----- apps/chapter_07.cpp | 4 +-- apps/chapter_09.cpp | 4 +-- raytracing/src/core/color.cpp | 17 ++++++---- raytracing/src/core/intersection-data.cpp | 19 +++++++++-- raytracing/src/core/intersection-data.h | 4 +++ raytracing/src/core/intersection.cpp | 10 +++--- raytracing/src/core/intersection.h | 2 +- raytracing/src/core/matrix.cpp | 21 +++++++----- raytracing/src/core/tuple.cpp | 21 ++++++------ raytracing/src/core/tuple.h | 2 +- raytracing/src/lights/point-light.cpp | 5 +-- raytracing/src/renderer/camera.cpp | 41 ++++++++++++----------- raytracing/src/renderer/canvas.cpp | 8 +++-- raytracing/src/renderer/material.cpp | 17 +++++++++- raytracing/src/renderer/material.h | 4 +++ raytracing/src/renderer/ray.cpp | 7 ++-- raytracing/src/renderer/ray.h | 2 +- raytracing/src/renderer/world.cpp | 9 ++--- raytracing/src/shapes/shape.cpp | 13 ++++--- raytracing/src/shapes/sphere.cpp | 2 +- tests/11_reflection_refraction.cpp | 38 +++++++++++++++++++++ 24 files changed, 184 insertions(+), 91 deletions(-) diff --git a/.clang-format b/.clang-format index 9d51fa7..1c8578a 100644 --- a/.clang-format +++ b/.clang-format @@ -20,6 +20,7 @@ DerivePointerAlignment: false PointerAlignment: Right ReferenceAlignment: Right AlignArrayOfStructures: Right +IndentCaseLabels: true # AlignConsecutiveAssignments: Consecutive AlignConsecutiveBitFields: Consecutive diff --git a/apps/chapter_05.cpp b/apps/chapter_05.cpp index 343cd01..4c5fa0e 100644 --- a/apps/chapter_05.cpp +++ b/apps/chapter_05.cpp @@ -50,7 +50,7 @@ int shadow_sphere(uint8_t a_canvas_pixels, double a_wall_size, uint8_t a_wall_z) Tuple the_ray_origin = Tuple::Point(0, 0, -5); double the_pixel_size = a_wall_size / a_canvas_pixels; - double the_half = a_wall_size / 2; + double the_half = a_wall_size / 2; double the_world_x, the_world_y; // For each row of pixels in the canvas @@ -70,7 +70,7 @@ int shadow_sphere(uint8_t a_canvas_pixels, double a_wall_size, uint8_t a_wall_z) the_position -= the_ray_origin; Ray the_ray(the_ray_origin, the_position.normalize()); - auto the_xs = the_shape.intersect(the_ray); + auto the_xs = the_shape.intersect(the_ray); auto the_intersec = the_xs.hit(); if (the_intersec.is_defined()) { @@ -94,8 +94,8 @@ int main(void) printf("Chapter 05 example.\n"); the_start = chrono::high_resolution_clock::now(); - the_ret = shadow_sphere(kImageSize, kWallSize, kWallZ); - the_end = chrono::high_resolution_clock::now(); + the_ret = shadow_sphere(kImageSize, kWallSize, kWallZ); + the_end = chrono::high_resolution_clock::now(); chrono::duration the_elapsed_time = the_end - the_start; printf("Execution Time: %f secondes\n", the_elapsed_time.count()); diff --git a/apps/chapter_06.cpp b/apps/chapter_06.cpp index 70ff7b6..f82f858 100644 --- a/apps/chapter_06.cpp +++ b/apps/chapter_06.cpp @@ -52,7 +52,7 @@ int shadow_sphere(uint8_t a_canvas_pixels, double a_wall_size, uint8_t a_wall_z) the_shape.material().set_color(Color(1, 0.2, 1)); double the_pixel_size = a_wall_size / a_canvas_pixels; - double the_half = a_wall_size / 2; + double the_half = a_wall_size / 2; double the_world_x, the_world_y; // For each row of pixels in the canvas @@ -72,15 +72,15 @@ int shadow_sphere(uint8_t a_canvas_pixels, double a_wall_size, uint8_t a_wall_z) the_position -= the_ray_origin; Ray the_ray(the_ray_origin, the_position.normalize()); - auto the_xs = the_shape.intersect(the_ray); + auto the_xs = the_shape.intersect(the_ray); auto the_intersec = the_xs.hit(); if (the_intersec.is_defined()) { - Tuple the_point = the_ray.position(the_intersec.distance_t()); + Tuple the_point = the_ray.position(the_intersec.distance_t()); Tuple the_normal = the_intersec.object()->normal_at(the_point); - Tuple the_eye = -the_ray.direction(); - Color the_color = the_intersec.object()->material().lighting(nullptr, the_light, the_point, the_eye, - the_normal, false); + Tuple the_eye = -the_ray.direction(); + Color the_color = the_intersec.object()->material().lighting(nullptr, the_light, the_point, the_eye, + the_normal, false); the_canvas.write_pixel(x, y, the_color); } } @@ -101,8 +101,8 @@ int main(void) printf("Chapter 06 example.\n"); the_start = chrono::high_resolution_clock::now(); - the_ret = shadow_sphere(kImageSize, kWallSize, kWallZ); - the_end = chrono::high_resolution_clock::now(); + the_ret = shadow_sphere(kImageSize, kWallSize, kWallZ); + the_end = chrono::high_resolution_clock::now(); chrono::duration the_elapsed_time = the_end - the_start; printf("Execution Time: %f secondes\n", the_elapsed_time.count()); diff --git a/apps/chapter_07.cpp b/apps/chapter_07.cpp index 6d639d6..a002b5c 100644 --- a/apps/chapter_07.cpp +++ b/apps/chapter_07.cpp @@ -107,9 +107,9 @@ int main(void) the_camera.set_transform( Matrix::view_transform(Tuple::Point(0, 1.5, -5), Tuple::Point(0, 1, 0), Tuple::Vector(0, 1, 0))); - the_start = chrono::high_resolution_clock::now(); + the_start = chrono::high_resolution_clock::now(); the_canvas = the_camera.render(the_world); - the_end = chrono::high_resolution_clock::now(); + the_end = chrono::high_resolution_clock::now(); the_canvas.save_to_file("chapter07.ppm"); diff --git a/apps/chapter_09.cpp b/apps/chapter_09.cpp index b7b6ca4..805d7da 100644 --- a/apps/chapter_09.cpp +++ b/apps/chapter_09.cpp @@ -91,9 +91,9 @@ int main(void) the_camera.set_transform( Matrix::view_transform(Tuple::Point(0, 1.5, -3.5), Tuple::Point(0, 1, 0), Tuple::Vector(0, 1, 0))); - the_start = chrono::high_resolution_clock::now(); + the_start = chrono::high_resolution_clock::now(); the_canvas = the_camera.render(the_world); - the_end = chrono::high_resolution_clock::now(); + the_end = chrono::high_resolution_clock::now(); the_canvas.save_to_file("chapter09.ppm"); diff --git a/raytracing/src/core/color.cpp b/raytracing/src/core/color.cpp index 800c5a2..0c79330 100644 --- a/raytracing/src/core/color.cpp +++ b/raytracing/src/core/color.cpp @@ -38,20 +38,23 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Color::Color(void) : m_red(0), m_green(0), m_blue(0) +Color::Color(void) : + m_red(0), m_green(0), m_blue(0) { // printf("%s red: %f green: %f, blue: %f\n", __PRETTY_FUNCTION__, m_red, m_green, m_blue); } /* ------------------------------------------------------------------------- */ -Color::Color(const Color &a_copy) : m_red(a_copy.m_red), m_green(a_copy.m_green), m_blue(a_copy.m_blue) +Color::Color(const Color &a_copy) : + m_red(a_copy.m_red), m_green(a_copy.m_green), m_blue(a_copy.m_blue) { } /* ------------------------------------------------------------------------- */ -Color::Color(double a_red, double a_green, double a_blue) : m_red(a_red), m_green(a_green), m_blue(a_blue) +Color::Color(double a_red, double a_green, double a_blue) : + m_red(a_red), m_green(a_green), m_blue(a_blue) { } @@ -77,9 +80,9 @@ const Color &Color::operator=(const Color &a_color) return *this; } - m_red = a_color.m_red; + m_red = a_color.m_red; m_green = a_color.m_green; - m_blue = a_color.m_blue; + m_blue = a_color.m_blue; return *this; } @@ -112,9 +115,9 @@ const Color Color::operator*(const Color &a_color) const // Using the hadamard product. double the_red, the_green, the_blue; - the_red = m_red * a_color.m_red; + the_red = m_red * a_color.m_red; the_green = m_green * a_color.m_green; - the_blue = m_blue * a_color.m_blue; + the_blue = m_blue * a_color.m_blue; return Color(the_red, the_green, the_blue); } diff --git a/raytracing/src/core/intersection-data.cpp b/raytracing/src/core/intersection-data.cpp index 8bd677a..c72864f 100644 --- a/raytracing/src/core/intersection-data.cpp +++ b/raytracing/src/core/intersection-data.cpp @@ -34,7 +34,8 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -IntersectionData::IntersectionData(void) : m_is_inside(false), m_distance(0), m_shape(nullptr) +IntersectionData::IntersectionData(void) : + m_is_inside(false), m_distance(0), m_shape(nullptr) { } @@ -124,6 +125,20 @@ void IntersectionData::set_normalv(const Tuple &a_normalv) /* ------------------------------------------------------------------------- */ +const Tuple &IntersectionData::reflectv(void) const +{ + return m_reflectv; +} + +/* ------------------------------------------------------------------------- */ + +void IntersectionData::set_reflectv(const Tuple &a_reflectv) +{ + m_reflectv = a_reflectv; +} + +/* ------------------------------------------------------------------------- */ + const bool IntersectionData::is_inside(void) const { return m_is_inside; @@ -136,7 +151,7 @@ void IntersectionData::set_inside(void) if (m_normalv.dot(m_eyev) < 0) { m_is_inside = true; - m_normalv = -m_normalv; + m_normalv = -m_normalv; } else { diff --git a/raytracing/src/core/intersection-data.h b/raytracing/src/core/intersection-data.h index 7b7483c..4e62eb8 100644 --- a/raytracing/src/core/intersection-data.h +++ b/raytracing/src/core/intersection-data.h @@ -59,6 +59,9 @@ namespace Raytracer const Tuple &normalv(void) const; void set_normalv(const Tuple &a_normalv); + const Tuple &reflectv(void) const; + void set_reflectv(const Tuple &a_reflectv); + const bool is_inside(void) const; void set_inside(void); @@ -70,6 +73,7 @@ namespace Raytracer Tuple m_over_point; Tuple m_eyev; Tuple m_normalv; + Tuple m_reflectv; }; }; // namespace Raytracer diff --git a/raytracing/src/core/intersection.cpp b/raytracing/src/core/intersection.cpp index 26e93b8..e612c33 100644 --- a/raytracing/src/core/intersection.cpp +++ b/raytracing/src/core/intersection.cpp @@ -36,7 +36,8 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Intersection::Intersection(void) : m_is_nothing(true), m_distance_t(0.0), m_shape(nullptr) +Intersection::Intersection(void) : + m_is_nothing(true), m_distance_t(0.0), m_shape(nullptr) { } @@ -78,7 +79,7 @@ const Intersection &Intersection::operator=(const Intersection &an_intersection) m_is_nothing = an_intersection.m_is_nothing; m_distance_t = an_intersection.m_distance_t; - m_shape = an_intersection.m_shape; + m_shape = an_intersection.m_shape; return *this; } @@ -162,11 +163,11 @@ bool Intersection::is_defined(void) /* ------------------------------------------------------------------------- */ -IntersectionData Intersection::prepare_computations(Ray a_ray) const +IntersectionData Intersection::prepare_computations(const Ray &a_ray) const { IntersectionData the_data; - // Copy intersections properties for conveniance + // Copy intersections properties for convenance the_data.set_distance_t(m_distance_t); the_data.set_object(m_shape); @@ -176,6 +177,7 @@ IntersectionData Intersection::prepare_computations(Ray a_ray) const the_data.set_normalv(m_shape->normal_at(the_data.point())); the_data.set_over_point(the_data.point() + the_data.normalv() * kEpsilon); the_data.set_inside(); + the_data.set_reflectv(a_ray.direction().reflect(the_data.normalv())); return the_data; } diff --git a/raytracing/src/core/intersection.h b/raytracing/src/core/intersection.h index 649db5d..986c52a 100644 --- a/raytracing/src/core/intersection.h +++ b/raytracing/src/core/intersection.h @@ -60,7 +60,7 @@ namespace Raytracer bool is_nothing(void); bool is_defined(void); - IntersectionData prepare_computations(Ray a_ray) const; + IntersectionData prepare_computations(const Ray &a_ray) const; private: bool m_is_nothing; diff --git a/raytracing/src/core/matrix.cpp b/raytracing/src/core/matrix.cpp index 9690e13..944cb8b 100644 --- a/raytracing/src/core/matrix.cpp +++ b/raytracing/src/core/matrix.cpp @@ -38,13 +38,15 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Matrix::Matrix(void) : m_rows(0), m_cols(0) +Matrix::Matrix(void) : + m_rows(0), m_cols(0) { } /* ------------------------------------------------------------------------- */ -Matrix::Matrix(uint8_t a_rows, uint8_t a_cols) : m_rows(a_rows), m_cols(a_cols) +Matrix::Matrix(uint8_t a_rows, uint8_t a_cols) : + m_rows(a_rows), m_cols(a_cols) { m_data = std::vector>(m_rows, std::vector(m_cols)); for (int i = 0; i < m_rows; i++) @@ -58,7 +60,8 @@ Matrix::Matrix(uint8_t a_rows, uint8_t a_cols) : m_rows(a_rows), m_cols(a_cols) /* ------------------------------------------------------------------------- */ -Matrix::Matrix(const Matrix &an_other) : m_rows(an_other.m_rows), m_cols(an_other.m_cols), m_data(an_other.m_data) +Matrix::Matrix(const Matrix &an_other) : + m_rows(an_other.m_rows), m_cols(an_other.m_cols), m_data(an_other.m_data) { } @@ -288,8 +291,8 @@ Matrix Matrix::inverse(void) const { for (int the_col = 0; the_col < m_cols; the_col++) { - the_cofactor = cofactor(the_row, the_col); - the_value = the_cofactor / the_determinant; + the_cofactor = cofactor(the_row, the_col); + the_value = the_cofactor / the_determinant; the_result[the_col][the_row] = the_value; } } @@ -399,11 +402,11 @@ Matrix Matrix::shearing(double a_xy, double a_xz, double a_yx, double a_yz, doub Matrix Matrix::view_transform(const Tuple &a_from, const Tuple &a_to, const Tuple &an_up) { - Tuple the_forward = (a_to - a_from).normalize(); + Tuple the_forward = (a_to - a_from).normalize(); Tuple the_up_normalized = an_up.normalize(); - Tuple the_left = the_forward.cross(the_up_normalized); - Tuple the_true_up = the_left.cross(the_forward); - Matrix the_orientation = { + Tuple the_left = the_forward.cross(the_up_normalized); + Tuple the_true_up = the_left.cross(the_forward); + Matrix the_orientation = { { the_left.x(), the_left.y(), the_left.z(), 0}, { the_true_up.x(), the_true_up.y(), the_true_up.z(), 0}, {-the_forward.x(), -the_forward.y(), -the_forward.z(), 0}, diff --git a/raytracing/src/core/tuple.cpp b/raytracing/src/core/tuple.cpp index 5115e71..bf5999a 100644 --- a/raytracing/src/core/tuple.cpp +++ b/raytracing/src/core/tuple.cpp @@ -40,25 +40,29 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Tuple::Tuple(void) : m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0) +Tuple::Tuple(void) : + m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0) { } /* ------------------------------------------------------------------------- */ -Tuple::Tuple(const Tuple &a_copy) : m_x(a_copy.m_x), m_y(a_copy.m_y), m_z(a_copy.m_z), m_w(a_copy.m_w) +Tuple::Tuple(const Tuple &a_copy) : + m_x(a_copy.m_x), m_y(a_copy.m_y), m_z(a_copy.m_z), m_w(a_copy.m_w) { } /* ------------------------------------------------------------------------- */ -Tuple::Tuple(double a_x, double a_y, double a_z, double a_w) : m_x(a_x), m_y(a_y), m_z(a_z), m_w(a_w) +Tuple::Tuple(double a_x, double a_y, double a_z, double a_w) : + m_x(a_x), m_y(a_y), m_z(a_z), m_w(a_w) { } /* ------------------------------------------------------------------------- */ -Tuple::Tuple(std::vector a_data) : m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0) +Tuple::Tuple(std::vector a_data) : + m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0) { int i = 0; for (auto the_it1 = a_data.cbegin(); the_it1 != a_data.cend(); ++the_it1) @@ -107,14 +111,9 @@ const Tuple &Tuple::operator=(const Tuple &an_other) /* ------------------------------------------------------------------------- */ -const Tuple &Tuple::operator-(void) +const Tuple Tuple::operator-(void) const { - m_x = -m_x; - m_y = -m_y; - m_z = -m_z; - m_w = -m_w; - - return *this; + return Tuple(-m_x, -m_y, -m_z, -m_w); } /* ------------------------------------------------------------------------- */ diff --git a/raytracing/src/core/tuple.h b/raytracing/src/core/tuple.h index b9212b5..045bc0b 100644 --- a/raytracing/src/core/tuple.h +++ b/raytracing/src/core/tuple.h @@ -49,7 +49,7 @@ namespace Raytracer bool operator==(const Tuple &an_other) const; const Tuple &operator=(const Tuple &an_other); - const Tuple &operator-(void); + const Tuple operator-(void) const; const Tuple operator+(const Tuple &an_other) const; const Tuple operator-(const Tuple &an_other) const; diff --git a/raytracing/src/lights/point-light.cpp b/raytracing/src/lights/point-light.cpp index f241324..53b3da9 100644 --- a/raytracing/src/lights/point-light.cpp +++ b/raytracing/src/lights/point-light.cpp @@ -44,7 +44,8 @@ PointLight::PointLight(const Tuple &a_position, const Color &an_intensity) : /* ------------------------------------------------------------------------- */ -PointLight::PointLight(const PointLight &a_light) : m_position(a_light.m_position), m_intensity(a_light.m_intensity) +PointLight::PointLight(const PointLight &a_light) : + m_position(a_light.m_position), m_intensity(a_light.m_intensity) { } @@ -57,7 +58,7 @@ const PointLight &PointLight::operator=(const PointLight &a_light) return *this; } - m_position = a_light.m_position; + m_position = a_light.m_position; m_intensity = a_light.m_intensity; return *this; diff --git a/raytracing/src/renderer/camera.cpp b/raytracing/src/renderer/camera.cpp index 276a2e1..65aab0a 100644 --- a/raytracing/src/renderer/camera.cpp +++ b/raytracing/src/renderer/camera.cpp @@ -39,7 +39,8 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Camera::Camera(void) : m_h_size(0), m_v_size(0), m_field_of_view(0), m_half_width(0), m_half_height(0), m_pixel_size(0) +Camera::Camera(void) : + m_h_size(0), m_v_size(0), m_field_of_view(0), m_half_width(0), m_half_height(0), m_pixel_size(0) { } @@ -55,17 +56,17 @@ Camera::Camera(uint16_t a_h_size, uint16_t a_v_size, double a_field_of_view) : m_pixel_size(0) { - double the_half_view = tan(m_field_of_view / 2); + double the_half_view = tan(m_field_of_view / 2); double the_aspect_ratio = (double)m_h_size / m_v_size; if (the_aspect_ratio >= 1) { - m_half_width = the_half_view; + m_half_width = the_half_view; m_half_height = the_half_view / the_aspect_ratio; } else { - m_half_width = the_half_view * the_aspect_ratio; + m_half_width = the_half_view * the_aspect_ratio; m_half_height = the_half_view; } // m_pixel_size = ceil(((m_half_width * 2) / m_h_size) * 100) / 100; @@ -76,13 +77,13 @@ Camera::Camera(uint16_t a_h_size, uint16_t a_v_size, double a_field_of_view) : Camera::Camera(const Camera &an_other) { - m_h_size = an_other.m_h_size; - m_v_size = an_other.m_v_size; + m_h_size = an_other.m_h_size; + m_v_size = an_other.m_v_size; m_field_of_view = an_other.m_field_of_view; - m_transform = an_other.m_transform; - m_half_width = an_other.m_half_width; - m_half_height = an_other.m_half_height; - m_pixel_size = an_other.m_pixel_size; + m_transform = an_other.m_transform; + m_half_width = an_other.m_half_width; + m_half_height = an_other.m_half_height; + m_pixel_size = an_other.m_pixel_size; } /* ------------------------------------------------------------------------- */ @@ -94,13 +95,13 @@ const Camera &Camera::operator=(const Camera &an_other) return *this; } - m_h_size = an_other.m_h_size; - m_v_size = an_other.m_v_size; + m_h_size = an_other.m_h_size; + m_v_size = an_other.m_v_size; m_field_of_view = an_other.m_field_of_view; - m_transform = an_other.m_transform; - m_half_width = an_other.m_half_width; - m_half_height = an_other.m_half_height; - m_pixel_size = an_other.m_pixel_size; + m_transform = an_other.m_transform; + m_half_width = an_other.m_half_width; + m_half_height = an_other.m_half_height; + m_pixel_size = an_other.m_pixel_size; return *this; } @@ -168,9 +169,9 @@ Ray Camera::ray_for_pixel(double an_x, double an_y) const // and then compute the ray direction vector. // (remember that the canvas is at z=-1) Matrix the_invert = m_transform.inverse(); - the_pixel = the_invert * Tuple::Point(the_world_x, the_world_y, -1); - the_origin = the_invert * Tuple::Point(0, 0, 0); - the_direction = (the_pixel - the_origin).normalize(); + the_pixel = the_invert * Tuple::Point(the_world_x, the_world_y, -1); + the_origin = the_invert * Tuple::Point(0, 0, 0); + the_direction = (the_pixel - the_origin).normalize(); return Ray(the_origin, the_direction); } @@ -186,7 +187,7 @@ Canvas Camera::render(const World &a_world) { for (int x = 0; x < m_h_size - 1; x++) { - Ray the_ray = ray_for_pixel(x, y); + Ray the_ray = ray_for_pixel(x, y); Color the_color = a_world.color_at(the_ray); the_image.write_pixel(x, y, the_color); } diff --git a/raytracing/src/renderer/canvas.cpp b/raytracing/src/renderer/canvas.cpp index 3620e95..72081e7 100644 --- a/raytracing/src/renderer/canvas.cpp +++ b/raytracing/src/renderer/canvas.cpp @@ -38,13 +38,15 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Canvas::Canvas(void) : m_width(0), m_height(0) +Canvas::Canvas(void) : + m_width(0), m_height(0) { } /* ------------------------------------------------------------------------- */ -Canvas::Canvas(uint16_t a_width, uint16_t a_height) : m_width(a_width), m_height(a_height) +Canvas::Canvas(uint16_t a_width, uint16_t a_height) : + m_width(a_width), m_height(a_height) { m_pixels = std::vector>(m_width, std::vector(m_height)); @@ -70,7 +72,7 @@ Canvas::Canvas(const Canvas &a_canvas) : Canvas &Canvas::operator=(const Canvas &a_canvas) { - m_width = a_canvas.m_width; + m_width = a_canvas.m_width; m_height = a_canvas.m_height; m_pixels = a_canvas.m_pixels; diff --git a/raytracing/src/renderer/material.cpp b/raytracing/src/renderer/material.cpp index 4be26af..fa65f86 100644 --- a/raytracing/src/renderer/material.cpp +++ b/raytracing/src/renderer/material.cpp @@ -47,6 +47,7 @@ Material::Material(void) : m_diffuse(0.9), m_specular(0.9), m_shininess(200), + m_reflective(0.0), m_pattern(nullptr) { } @@ -57,7 +58,7 @@ bool Material::operator==(const Material &a_material) const { return (m_color == a_material.m_color) && double_equal(m_ambient, a_material.m_ambient) && double_equal(m_diffuse, a_material.m_diffuse) && double_equal(m_specular, a_material.m_specular) && - double_equal(m_shininess, a_material.m_shininess); + double_equal(m_shininess, a_material.m_shininess) && double_equal(m_reflective, a_material.m_reflective); // TODO m_pattern } @@ -133,6 +134,20 @@ void Material::set_shininess(double a_value) /* ------------------------------------------------------------------------- */ +const double &Material::reflective(void) const +{ + return m_reflective; +} + +/* ------------------------------------------------------------------------- */ + +void Material::set_reflective(double a_value) +{ + m_reflective = a_value; +} + +/* ------------------------------------------------------------------------- */ + Pattern *Material::pattern(void) { return m_pattern; diff --git a/raytracing/src/renderer/material.h b/raytracing/src/renderer/material.h index 9457926..54ff466 100644 --- a/raytracing/src/renderer/material.h +++ b/raytracing/src/renderer/material.h @@ -62,6 +62,9 @@ namespace Raytracer const double &shininess(void) const; void set_shininess(double a_value); + const double &reflective(void) const; + void set_reflective(double a_value); + Pattern *pattern(void); void set_pattern(Pattern *a_pattern); @@ -74,6 +77,7 @@ namespace Raytracer double m_diffuse; double m_specular; double m_shininess; + double m_reflective; Pattern *m_pattern; }; }; // namespace Raytracer diff --git a/raytracing/src/renderer/ray.cpp b/raytracing/src/renderer/ray.cpp index a84cb81..852d9c3 100644 --- a/raytracing/src/renderer/ray.cpp +++ b/raytracing/src/renderer/ray.cpp @@ -35,7 +35,8 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Ray::Ray(Tuple an_origin, Tuple a_direction) : m_origin(an_origin), m_direction(a_direction) +Ray::Ray(Tuple an_origin, Tuple a_direction) : + m_origin(an_origin), m_direction(a_direction) { } @@ -62,7 +63,7 @@ Tuple &Ray::direction(void) /* ------------------------------------------------------------------------- */ -Tuple Ray::position(double a_distance) +Tuple Ray::position(double a_distance) const { return m_origin + m_direction * a_distance; } @@ -73,7 +74,7 @@ Ray Ray::transform(const Matrix &a_matrix) const { Ray the_output_ray; - the_output_ray.m_origin = a_matrix * m_origin; + the_output_ray.m_origin = a_matrix * m_origin; the_output_ray.m_direction = a_matrix * m_direction; return the_output_ray; diff --git a/raytracing/src/renderer/ray.h b/raytracing/src/renderer/ray.h index 2b6494f..e48c2e0 100644 --- a/raytracing/src/renderer/ray.h +++ b/raytracing/src/renderer/ray.h @@ -45,7 +45,7 @@ namespace Raytracer const Tuple &direction(void) const; Tuple &direction(void); - Tuple position(double a_distance); + Tuple position(double a_distance) const; Ray transform(const Matrix &a_matrix) const; diff --git a/raytracing/src/renderer/world.cpp b/raytracing/src/renderer/world.cpp index 410c828..47c7d34 100644 --- a/raytracing/src/renderer/world.cpp +++ b/raytracing/src/renderer/world.cpp @@ -39,7 +39,8 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -World::World(void) : m_has_light(false) +World::World(void) : + m_has_light(false) { } @@ -106,7 +107,7 @@ const PointLight &World::light(void) const void World::set_light(const PointLight &a_light) { - m_light = a_light; + m_light = a_light; m_has_light = true; } @@ -194,13 +195,13 @@ Color World::color_at(const Ray &a_ray) const bool World::is_shadowed(const Tuple &a_point) const { - Tuple the_v = m_light.position() - a_point; + Tuple the_v = m_light.position() - a_point; double the_distance = the_v.magnitude(); Tuple the_direction = the_v.normalize(); Ray the_ray(a_point, the_direction); Intersections the_intersections = intersect_world(the_ray); - Intersection the_h = the_intersections.hit(); + Intersection the_h = the_intersections.hit(); if ((the_h.is_defined()) && (the_h.distance_t() < the_distance)) { diff --git a/raytracing/src/shapes/shape.cpp b/raytracing/src/shapes/shape.cpp index 710124f..cf55f34 100644 --- a/raytracing/src/shapes/shape.cpp +++ b/raytracing/src/shapes/shape.cpp @@ -40,19 +40,22 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ -Shape::Shape(void) : m_transform(Matrix::identity()) +Shape::Shape(void) : + m_transform(Matrix::identity()) { } /* ------------------------------------------------------------------------- */ -Shape::Shape(Shape &a_copy) : m_transform(a_copy.m_transform), m_material(a_copy.m_material) +Shape::Shape(Shape &a_copy) : + m_transform(a_copy.m_transform), m_material(a_copy.m_material) { } /* ------------------------------------------------------------------------- */ -Shape::Shape(const Shape &a_copy) : m_transform(a_copy.m_transform), m_material(a_copy.m_material) +Shape::Shape(const Shape &a_copy) : + m_transform(a_copy.m_transform), m_material(a_copy.m_material) { } @@ -66,7 +69,7 @@ const Shape &Shape::operator=(const Shape &a_shape) } m_transform = a_shape.m_transform; - m_material = a_shape.m_material; + m_material = a_shape.m_material; return *this; } @@ -131,7 +134,7 @@ void Shape::set_material(const Material &a_material) Tuple Shape::normal_at(const Tuple &a_world_point) const { - Tuple the_local_point = m_transform.inverse() * a_world_point; + Tuple the_local_point = m_transform.inverse() * a_world_point; Tuple the_local_normal = local_normal_at(the_local_point); Tuple the_world_normal = m_transform.inverse().transpose() * the_local_normal; the_world_normal.set_w(0); diff --git a/raytracing/src/shapes/sphere.cpp b/raytracing/src/shapes/sphere.cpp index b653fee..eb86371 100644 --- a/raytracing/src/shapes/sphere.cpp +++ b/raytracing/src/shapes/sphere.cpp @@ -43,7 +43,7 @@ Intersections Sphere::local_intersect(const Ray &a_ray) { Intersections the_intersections; Tuple the_sphere_to_ray = a_ray.origin() - Tuple::Point(0, 0, 0); - Tuple the_direction = a_ray.direction(); + Tuple the_direction = a_ray.direction(); double the_a = the_direction.dot(the_direction); double the_b = 2 * the_direction.dot(the_sphere_to_ray); diff --git a/tests/11_reflection_refraction.cpp b/tests/11_reflection_refraction.cpp index 71529b3..6ed2359 100644 --- a/tests/11_reflection_refraction.cpp +++ b/tests/11_reflection_refraction.cpp @@ -32,3 +32,41 @@ using namespace Raytracer; /* ------------------------------------------------------------------------- */ + +SCENARIO("Reflectivity for the default material", "[features/materials.feature]") +{ + GIVEN("m <- material()") + { + Material m; + THEN("m.reflective = 0.0") + { + REQUIRE(m.reflective() == 0); + } + } +} + +/* ------------------------------------------------------------------------- */ + +SCENARIO("Precomputing the reflection vector", "[features/intersections.feature]") +{ + GIVEN("shape <- plane()") + { + Plane shape; + AND_GIVEN("r <- ray(point(0, 1, -1), vector(0, -sqrt(2)/2, sqrt(2)/2))") + { + Ray r(Tuple::Point(0, 1, -1), Tuple::Vector(0, -sqrt(2) / 2, sqrt(2) / 2)); + AND_GIVEN("i <- intersection(sqrt(2), shape)") + { + Intersection i(sqrt(2), &shape); + WHEN("comps <- prepare_computation(i, r)") + { + IntersectionData comps = i.prepare_computations(r); + THEN("comps.reflectv = vector(0, sqrt(2) / 2, sqrt(2) / 2)") + { + REQUIRE(comps.reflectv() == Tuple::Vector(0, sqrt(2) / 2, sqrt(2) / 2)); + } + } + } + } + } +}