[FEAT] Add PointLight & Material

This commit is contained in:
2024-02-19 22:56:26 +01:00
parent cb4149ae60
commit ee5b2c1c95
9 changed files with 412 additions and 0 deletions

View File

@@ -14,7 +14,9 @@ add_library(raytracing
src/color.cpp src/color.cpp
src/intersection.cpp src/intersection.cpp
src/intersections.cpp src/intersections.cpp
src/material.cpp
src/matrix.cpp src/matrix.cpp
src/point-light.cpp
src/shape.cpp src/shape.cpp
src/ray.cpp src/ray.cpp
src/sphere.cpp src/sphere.cpp

View File

@@ -30,7 +30,9 @@
#include "common.h" #include "common.h"
#include "intersection.h" #include "intersection.h"
#include "intersections.h" #include "intersections.h"
#include "material.h"
#include "matrix.h" #include "matrix.h"
#include "point-light.h"
#include "ray.h" #include "ray.h"
#include "sphere.h" #include "sphere.h"
#include "tuple.h" #include "tuple.h"

113
raytracing/src/material.cpp Normal file
View File

@@ -0,0 +1,113 @@
/*!
* material.cpp
*
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 19/02/2024
*
*/
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
/* ------------------------------------------------------------------------- */
#include "common.h"
#include "material.h"
using namespace Raytracer;
/* ------------------------------------------------------------------------- */
Material::Material(void) : m_color(1, 1, 1), m_ambient(0.1), m_diffuse(0.9), m_specular(0.9), m_shininess(200)
{
}
/* ------------------------------------------------------------------------- */
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);
}
/* ------------------------------------------------------------------------- */
const Color &Material::color(void) const
{
return m_color;
}
/* ------------------------------------------------------------------------- */
const double &Material::ambient(void) const
{
return m_ambient;
}
/* ------------------------------------------------------------------------- */
void Material::set_ambient(double a_value)
{
m_ambient = a_value;
}
/* ------------------------------------------------------------------------- */
const double &Material::diffuse(void) const
{
return m_diffuse;
}
/* ------------------------------------------------------------------------- */
void Material::set_diffuse(double a_value)
{
m_diffuse = a_value;
}
/* ------------------------------------------------------------------------- */
const double &Material::specular(void) const
{
return m_specular;
}
/* ------------------------------------------------------------------------- */
void Material::set_specular(double a_value)
{
m_specular = a_value;
}
/* ------------------------------------------------------------------------- */
const double &Material::shininess(void) const
{
return m_shininess;
}
/* ------------------------------------------------------------------------- */
void Material::set_shininess(double a_value)
{
m_shininess = a_value;
}

67
raytracing/src/material.h Normal file
View File

@@ -0,0 +1,67 @@
/*!
* material.h
*
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 19/02/2024
*
*/
#ifndef _RAYTRACER_MATERIAL_H
#define _RAYTRACER_MATERIAL_H
/* ------------------------------------------------------------------------- */
#include "color.h"
/* ------------------------------------------------------------------------- */
namespace Raytracer
{
class Material
{
public:
Material(void);
bool operator==(const Material &a_material) const;
const Color &color(void) const;
const double &ambient(void) const;
void set_ambient(double a_value);
const double &diffuse(void) const;
void set_diffuse(double a_value);
const double &specular(void) const;
void set_specular(double a_value);
const double &shininess(void) const;
void set_shininess(double a_value);
private:
Color m_color;
double m_ambient;
double m_diffuse;
double m_specular;
double m_shininess;
};
}; // namespace Raytracer
#endif /* _RAYTRACER_MATERIAL_H */

View File

@@ -0,0 +1,57 @@
/*!
* point-light.cpp
*
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 19/02/2024
*
*/
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
/* ------------------------------------------------------------------------- */
#include "common.h"
#include "point-light.h"
using namespace Raytracer;
/* ------------------------------------------------------------------------- */
PointLight::PointLight(const Tuple &a_position, const Color &an_intensity) :
m_position(a_position),
m_intensity(an_intensity)
{
}
/* ------------------------------------------------------------------------- */
const Tuple &PointLight::position(void) const
{
return m_position;
}
/* ------------------------------------------------------------------------- */
const Color &PointLight::intensity(void) const
{
return m_intensity;
}

View File

@@ -0,0 +1,52 @@
/*!
* point-light.h
*
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 19/02/2024
*
*/
#ifndef _RAYTRACER_POINT_LIGHT_H
#define _RAYTRACER_POINT_LIGHT_H
/* ------------------------------------------------------------------------- */
#include "color.h"
#include "tuple.h"
/* ------------------------------------------------------------------------- */
namespace Raytracer
{
class PointLight
{
public:
PointLight(const Tuple &a_position, const Color &an_intensity);
const Tuple &position(void) const;
const Color &intensity(void) const;
private:
Tuple m_position;
Color m_intensity;
};
}; // namespace Raytracer
#endif /* _RAYTRACER_POINT_LIGHT_H */

View File

@@ -96,6 +96,20 @@ void Shape::set_transform(const Matrix &a_transform_matrix)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
const Material &Shape::material(void) const
{
return m_material;
}
/* ------------------------------------------------------------------------- */
void Shape::set_material(const Material &a_material)
{
m_material = a_material;
}
/* ------------------------------------------------------------------------- */
Tuple Shape::normal_at(const Tuple &a_world_point) Tuple Shape::normal_at(const Tuple &a_world_point)
{ {
Tuple the_object_point = m_transform.inverse() * a_world_point; Tuple the_object_point = m_transform.inverse() * a_world_point;

View File

@@ -30,6 +30,7 @@
#include <cstdint> #include <cstdint>
#include "material.h"
#include "matrix.h" #include "matrix.h"
#include "ray.h" #include "ray.h"
@@ -54,6 +55,9 @@ namespace Raytracer
Matrix &transform(void); Matrix &transform(void);
void set_transform(const Matrix &a_transform_matrix); void set_transform(const Matrix &a_transform_matrix);
const Material &material(void) const;
void set_material(const Material &a_material);
Tuple normal_at(const Tuple &a_point); Tuple normal_at(const Tuple &a_point);
virtual Intersections intersect(Ray &a_ray); virtual Intersections intersect(Ray &a_ray);
@@ -64,6 +68,7 @@ namespace Raytracer
private: private:
uint32_t m_id; uint32_t m_id;
Matrix m_transform; Matrix m_transform;
Material m_material;
static uint32_t s_current_index; static uint32_t s_current_index;
}; };
}; // namespace Raytracer }; // namespace Raytracer

View File

@@ -212,3 +212,103 @@ SCENARIO("Reflecting a vector off a slanted surface", "[features/tuples.feature]
} }
} }
} }
/* ------------------------------------------------------------------------- */
SCENARIO("A point light has a position and intensity", "[features/lights.feature]")
{
GIVEN("intensity <- color(1, 1, 1)")
{
Color intensity(1, 1, 1);
AND_GIVEN("position <- point(0, 0, 0)")
{
Tuple position = Tuple::Point(0, 0, 0);
WHEN("light <- point_light(position(position, intensity))")
{
PointLight light = PointLight(position, intensity);
THEN("light.position = position")
{
REQUIRE(light.position() == position);
}
AND_THEN("light.intensity = intensity")
{
REQUIRE(light.intensity() == intensity);
}
}
}
}
}
/* ------------------------------------------------------------------------- */
SCENARIO("The default material", "[features/materials.feature]")
{
GIVEN("m <- material()")
{
Material m;
THEN("m.color = color(1,1,1)")
{
REQUIRE(m.color() == Color(1, 1, 1));
}
AND_THEN("m.ambient = 0.1")
{
REQUIRE(m.ambient() == 0.1);
}
AND_THEN("m.diffuse = 0.9")
{
REQUIRE(m.diffuse() == 0.9);
}
AND_THEN("m.specular = 0.9")
{
REQUIRE(m.specular() == 0.9);
}
AND_THEN("m.shininess = 200.0")
{
REQUIRE(m.shininess() == 200.0);
}
}
}
/* ------------------------------------------------------------------------- */
SCENARIO("A sphere has a default material", "[features/spheres.feature]")
{
GIVEN("s <- sphere()")
{
Sphere s;
WHEN("m <- s.material")
{
Material m = s.material();
THEN("m = material()")
{
REQUIRE(m == Material());
}
}
}
}
/* ------------------------------------------------------------------------- */
SCENARIO("A sphere may be assigned a material", "[features/spheres.feature]")
{
GIVEN("s <- sphere()")
{
Sphere s;
AND_GIVEN("m <- material")
{
Material m;
AND_GIVEN("m.ambient <- 1")
{
m.set_ambient(1);
WHEN("s.material <- m")
{
s.set_material(m);
THEN("s.material = m")
{
s.material() == m;
}
}
}
}
}
}