[WIP] Add reflective parameter into material

This commit is contained in:
NADAL Jean-Baptiste
2024-03-05 17:01:38 +01:00
parent 17a75a841d
commit 41ea86d3ec
24 changed files with 184 additions and 91 deletions

View File

@@ -20,6 +20,7 @@ DerivePointerAlignment: false
PointerAlignment: Right PointerAlignment: Right
ReferenceAlignment: Right ReferenceAlignment: Right
AlignArrayOfStructures: Right AlignArrayOfStructures: Right
IndentCaseLabels: true
# AlignConsecutiveAssignments: Consecutive # AlignConsecutiveAssignments: Consecutive
AlignConsecutiveBitFields: Consecutive AlignConsecutiveBitFields: Consecutive

View File

@@ -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); // 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)
{ {
} }

View File

@@ -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 const bool IntersectionData::is_inside(void) const
{ {
return m_is_inside; return m_is_inside;

View File

@@ -59,6 +59,9 @@ namespace Raytracer
const Tuple &normalv(void) const; const Tuple &normalv(void) const;
void set_normalv(const Tuple &a_normalv); 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; const bool is_inside(void) const;
void set_inside(void); void set_inside(void);
@@ -70,6 +73,7 @@ namespace Raytracer
Tuple m_over_point; Tuple m_over_point;
Tuple m_eyev; Tuple m_eyev;
Tuple m_normalv; Tuple m_normalv;
Tuple m_reflectv;
}; };
}; // namespace Raytracer }; // namespace Raytracer

View File

@@ -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)
{ {
} }
@@ -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; IntersectionData the_data;
// Copy intersections properties for conveniance // Copy intersections properties for convenance
the_data.set_distance_t(m_distance_t); the_data.set_distance_t(m_distance_t);
the_data.set_object(m_shape); 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_normalv(m_shape->normal_at(the_data.point()));
the_data.set_over_point(the_data.point() + the_data.normalv() * kEpsilon); the_data.set_over_point(the_data.point() + the_data.normalv() * kEpsilon);
the_data.set_inside(); the_data.set_inside();
the_data.set_reflectv(a_ray.direction().reflect(the_data.normalv()));
return the_data; return the_data;
} }

View File

@@ -60,7 +60,7 @@ namespace Raytracer
bool is_nothing(void); bool is_nothing(void);
bool is_defined(void); bool is_defined(void);
IntersectionData prepare_computations(Ray a_ray) const; IntersectionData prepare_computations(const Ray &a_ray) const;
private: private:
bool m_is_nothing; bool m_is_nothing;

View File

@@ -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<std::vector<double>>(m_rows, std::vector<double>(m_cols)); m_data = std::vector<std::vector<double>>(m_rows, std::vector<double>(m_cols));
for (int i = 0; i < m_rows; i++) 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)
{ {
} }

View File

@@ -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<double> a_data) : m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0) Tuple::Tuple(std::vector<double> a_data) :
m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0)
{ {
int i = 0; int i = 0;
for (auto the_it1 = a_data.cbegin(); the_it1 != a_data.cend(); ++the_it1) 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; return Tuple(-m_x, -m_y, -m_z, -m_w);
m_y = -m_y;
m_z = -m_z;
m_w = -m_w;
return *this;
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@@ -49,7 +49,7 @@ namespace Raytracer
bool operator==(const Tuple &an_other) const; bool operator==(const Tuple &an_other) const;
const Tuple &operator=(const Tuple &an_other); 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;
const Tuple operator-(const Tuple &an_other) const; const Tuple operator-(const Tuple &an_other) const;

View File

@@ -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)
{ {
} }

View File

@@ -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)
{ {
} }

View File

@@ -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<std::vector<Color>>(m_width, std::vector<Color>(m_height)); m_pixels = std::vector<std::vector<Color>>(m_width, std::vector<Color>(m_height));

View File

@@ -47,6 +47,7 @@ Material::Material(void) :
m_diffuse(0.9), m_diffuse(0.9),
m_specular(0.9), m_specular(0.9),
m_shininess(200), m_shininess(200),
m_reflective(0.0),
m_pattern(nullptr) 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) && 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_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 // 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) Pattern *Material::pattern(void)
{ {
return m_pattern; return m_pattern;

View File

@@ -62,6 +62,9 @@ namespace Raytracer
const double &shininess(void) const; const double &shininess(void) const;
void set_shininess(double a_value); void set_shininess(double a_value);
const double &reflective(void) const;
void set_reflective(double a_value);
Pattern *pattern(void); Pattern *pattern(void);
void set_pattern(Pattern *a_pattern); void set_pattern(Pattern *a_pattern);
@@ -74,6 +77,7 @@ namespace Raytracer
double m_diffuse; double m_diffuse;
double m_specular; double m_specular;
double m_shininess; double m_shininess;
double m_reflective;
Pattern *m_pattern; Pattern *m_pattern;
}; };
}; // namespace Raytracer }; // namespace Raytracer

View File

@@ -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; return m_origin + m_direction * a_distance;
} }

View File

@@ -45,7 +45,7 @@ namespace Raytracer
const Tuple &direction(void) const; const Tuple &direction(void) const;
Tuple &direction(void); Tuple &direction(void);
Tuple position(double a_distance); Tuple position(double a_distance) const;
Ray transform(const Matrix &a_matrix) const; Ray transform(const Matrix &a_matrix) const;

View File

@@ -39,7 +39,8 @@ using namespace Raytracer;
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
World::World(void) : m_has_light(false) World::World(void) :
m_has_light(false)
{ {
} }

View File

@@ -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)
{ {
} }

View File

@@ -32,3 +32,41 @@
using namespace Raytracer; 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));
}
}
}
}
}
}