Skip to content

Commit

Permalink
Merge pull request #35 from BardoBard/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
BardoBard authored May 30, 2024
2 parents c6de720 + bfd2e69 commit f4e27cc
Show file tree
Hide file tree
Showing 24 changed files with 467 additions and 172 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/Build-Test-Cmake.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# .github/workflows/build-job.yml
name: Build Job
name: Build And Test CMake

on:
workflow_call:
Expand Down
53 changes: 25 additions & 28 deletions Bardrix/include/bardrix/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,42 @@ namespace bardrix {
/// Diffuse light is the light that is reflected off the surface of the object
/// Think of it as light that is scattered in all directions when it hits the object
/// \details Diffuse light has to be between 0 and 1, where 0 is no diffuse light and 1 is full diffuse light
/// \note Diffuse light is the opposite of specular light, both components add up to 1
double diffuse_ = 1;

/// \brief The specular coefficient, between 0 and 1
/// Specular light is the light that is reflected off the surface of the object in a mirror-like way
/// Think of it as the light that is reflected in a specific direction when it hits the object
/// \details Specular light has to be between 0 and 1, where 0 is no specular light and 1 is full specular light
/// \note Specular light is the opposite of diffuse light, both components add up to 1
double specular_ = 0;

/// \brief The shininess coefficient, between 0 and infinity
/// \brief The shininess coefficient, between 1 and infinity
/// Shininess is the size of the specular highlight
/// Think of it as the size of the reflection of the light
/// \details Shininess has to be between 0 and infinity, where 0 is no shininess and 1 is full shininess
/// \details Shininess has to be between 1 and infinity, where 1 leads to broad highlights and infinity leads to sharp highlights
double shininess_ = 0;

public:
/// \brief Default constructor for material
/// \note The default material is white with no ambient, full diffuse, no specular and no shininess
material() = default;
material() noexcept;

/// \brief Constructor for material
/// \param ambient The ambient coefficient
/// \param diffuse The diffuse coefficient, the specular coefficient will be set to 1 - diffuse
/// \param shininess The shininess coefficient
/// \example material material(0.5, 0.1, 0.5); -> color = white, ambient = 0.5, diffuse = 0.1, specular = 0.9, shininess = 0.5
material(double ambient, double diffuse, double shininess);
/// \param ambient The ambient coefficient [0, 1]
/// \param diffuse The diffuse coefficient [0, 1]
/// \param specular The specular coefficient [0, 1]
/// \param shininess The shininess coefficient [1, infinity]
/// \example material material(0.5, 0.1, 0.9, 50); -> color = white, ambient = 0.5, diffuse = 0.1, specular = 0.9, shininess = 50
material(double ambient, double diffuse, double specular, double shininess) noexcept;

/// \brief Constructor for material
/// \param ambient The ambient coefficient [0, 1]
/// \param diffuse The diffuse coefficient [0, 1]
/// \param specular The specular coefficient [0, 1]
/// \param shininess The shininess coefficient [1, infinity]
/// \param color The color of the material
/// \param ambient The ambient coefficient
/// \param diffuse The diffuse coefficient, the specular coefficient will be set to 1 - diffuse
/// \param shininess The shininess coefficient
/// \example material material(color::red(), 0.5, 0.1, 0.5); -> color = red, ambient = 0.5, diffuse = 0.1, specular = 0.9, shininess = 0.5
material(const bardrix::color& color, double ambient, double diffuse, double shininess);
/// \example material material(0.5, 0.1, 0.9, 50, bardrix::color::red()); -> color = red, ambient = 0.5, diffuse = 0.1, specular = 0.9, shininess = 50
material(double ambient, double diffuse, double specular, double shininess,
const bardrix::color& color) noexcept;

/// \brief Gets the ambient coefficient
/// \return The ambient coefficient, between 0 and 1
Expand All @@ -82,13 +83,12 @@ namespace bardrix {
/// \return The diffuse coefficient, between 0 and 1
NODISCARD double get_diffuse() const;

/// \brief Sets the diffuse and specular coefficients
/// \brief Sets the diffuse
/// \param diffuse The diffuse coefficient
/// \details This method sets the diffuse and specular coefficients, ensuring that they add up to 1
/// \note If the diffuse coefficient is less than 0, it will be set to 0
/// \note If the diffuse coefficient is greater than 1, it will be set to 1
/// \example material.set_diffuse(0.5); -> diffuse = 0.5, specular = 0.5
/// \example material.set_diffuse(0.8); -> diffuse = 0.8, specular = 0.2
/// \example material.set_diffuse(0.5); -> diffuse = 0.5
/// \example material.set_diffuse(1.8); -> diffuse = 1
void set_diffuse(double diffuse);

/// \brief Gets the specular coefficient
Expand All @@ -97,25 +97,22 @@ namespace bardrix {

/// \brief Sets the specular coefficient
/// \param specular The specular coefficient
/// \details This method sets the specular and diffuse coefficients, ensuring that they add up to 1
/// \note If the specular coefficient is less than 0, it will be set to 0
/// \note If the specular coefficient is greater than 1, it will be set to 1
/// \example material.set_specular(0.5); -> diffuse = 0.5, specular = 0.5
/// \example material.set_specular(0.8); -> diffuse = 0.2, specular = 0.8
/// \example material.set_specular(0.5); -> specular = 0.5
/// \example material.set_specular(1.8); -> specular = 1
void set_specular(double specular);

/// \brief Gets the shininess coefficient
/// \return The shininess coefficient, between 0 and infinity
/// \return The shininess coefficient, between 1 and infinity
NODISCARD double get_shininess() const;

/// \brief Sets the shininess coefficient
/// \param shininess The shininess coefficient
/// \note If the shininess coefficient is less than 0, it will be set to 0
/// \note If the shininess coefficient is greater than 1, it will be set to 1
/// \example material.set_shininess(0.5); -> shininess = 0.5
/// \example material.set_shininess(1.8); -> shininess = 1
/// \note If the shininess coefficient is less than 1, it will be set to 1
/// \example material.set_shininess(0.5); -> shininess = 1
/// \example material.set_shininess(50); -> shininess = 50
void set_shininess(double shininess);

};

/// \brief A pure virtual class for a 3D shape
Expand Down
5 changes: 3 additions & 2 deletions Bardrix/include/bardrix/vector3.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,17 @@ namespace bardrix {
NODISCARD double angle(const vector3& vec3) const;

/// \brief Calculates the reflection of this vector onto a normal
/// The result will be an outgoing normalized vector
/// The result will be an outgoing vector with the same length as the incoming vector
/// \param normal The normal vector, will be normalized for you
/// \note If the incoming vector or the normal vector has length 0, it will return std::nullopt
/// \note If the incoming vector is behind the normal, it will return std::nullopt
/// \return reflection of this vector on a normalized normal, if a degenerate case is found, it will return std::nullopt
/// \details formula: r = n (2 * (d . n)) − d
/// \details r is the reflection
/// \details n is the normal
/// \details n is the normal (normalized)
/// \details d is the vector
/// \see https://math.stackexchange.com/a/4019883
/// \see bardrix::quaternion::mirror for the same functionality
NODISCARD std::optional<vector3> reflection(const vector3& normal) const;

/// \brief Calculates the refraction of this vector through a normal
Expand Down
13 changes: 8 additions & 5 deletions Bardrix/src/bardrix/objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@

namespace bardrix {

material::material(const double ambient, const double diffuse, const double shininess) : material(color::white(), ambient, diffuse, shininess) {}
material::material() noexcept : material(0, 1, 0, 0, bardrix::color::white()) {}

material::material(const bardrix::color& color, const double ambient, const double diffuse, const double shininess) : color(color) {
material::material(const double ambient, const double diffuse, const double specular, const double shininess) noexcept
: material(ambient, diffuse, specular, shininess, color::white()) {}

material::material(const double ambient, const double diffuse, const double specular, const double shininess,
const bardrix::color& color) noexcept : color(color) {
set_ambient(ambient);
set_diffuse(diffuse);
set_specular(specular);
set_shininess(shininess);
}

Expand All @@ -22,18 +27,16 @@ namespace bardrix {

void material::set_diffuse(const double diffuse) {
diffuse_ = std::clamp(diffuse, 0.0, 1.0);
specular_ = 1 - diffuse_;
}

double material::get_specular() const { return specular_; }

void material::set_specular(const double specular) {
specular_ = std::clamp(specular, 0.0, 1.0);
diffuse_ = 1 - specular_;
}

double material::get_shininess() const { return shininess_; }

void material::set_shininess(const double shininess) { shininess_ = std::clamp(shininess, 0.0, 1.0); }
void material::set_shininess(const double shininess) { shininess_ = std::max(1.0, shininess); }

} // namespace bardrix
5 changes: 2 additions & 3 deletions Bardrix/src/bardrix/vector3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,14 @@ namespace bardrix {
return std::nullopt;

const vector3 normalized_normal = normal.normalized();
const vector3 normalized_vector = this->normalized();
const double dot = normalized_normal.dot(normalized_vector);
const double dot = this->dot(normalized_normal);

// Dot < 0 means the vector is behind the normal
// We're unable to reflect a vector that is behind the normal
if (dot < 0)
return std::nullopt;

return -(normalized_normal * (2 * dot) - normalized_vector);
return normalized_normal * 2 * dot - *this;
}

std::optional<vector3> vector3::refraction(const vector3& normal, double refractive_ratio) const {
Expand Down
38 changes: 16 additions & 22 deletions Bardrix_Tests/tests/objects_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,44 @@ TEST(material, default_constructor) {
EXPECT_EQ(material.get_ambient(), 0);
EXPECT_EQ(material.get_diffuse(), 1);
EXPECT_EQ(material.get_specular(), 0);
EXPECT_EQ(material.get_shininess(), 0);
EXPECT_EQ(material.get_shininess(), 1);
}

TEST(material, constructor_ambient_diffuse_shininess) {
bardrix::material material = bardrix::material(0.1, 0.2, 0.3);
bardrix::material material = bardrix::material(0.1, 0.2, 0.3, 1);

EXPECT_EQ(material.color, bardrix::color::white());
EXPECT_EQ(material.get_ambient(), 0.1);
EXPECT_EQ(material.get_diffuse(), 0.2);
EXPECT_EQ(material.get_specular(), 0.8);
EXPECT_EQ(material.get_shininess(), 0.3);
EXPECT_EQ(material.get_specular(), 0.3);
EXPECT_EQ(material.get_shininess(), 1);
}

/// \brief Test the material constructor
TEST(material, constructor) {
bardrix::material material = bardrix::material(bardrix::color::red(), 0.1, 0.2, 0.3);
bardrix::material material = bardrix::material(0.1, 0.2, 0.3, 1, bardrix::color::red());

EXPECT_EQ(material.color, bardrix::color::red());
EXPECT_EQ(material.get_ambient(), 0.1);
EXPECT_EQ(material.get_diffuse(), 0.2);
EXPECT_EQ(material.get_specular(), 0.8);
EXPECT_EQ(material.get_shininess(), 0.3);
EXPECT_EQ(material.get_specular(), 0.3);
EXPECT_EQ(material.get_shininess(), 1);
}

/// \brief Test the material constructor with degenerate values
TEST(material, constructor_degenerate) {
bardrix::material material = bardrix::material(bardrix::color::red(), -0.1, 1.2, -0.3);
bardrix::material material = bardrix::material(-0.1, 1.2, -0.3, 0, bardrix::color::red());

EXPECT_EQ(material.color, bardrix::color::red());
EXPECT_EQ(material.get_ambient(), 0);
EXPECT_EQ(material.get_diffuse(), 1);
EXPECT_EQ(material.get_specular(), 0);
EXPECT_EQ(material.get_shininess(), 0);
EXPECT_EQ(material.get_shininess(), 1);
}

/// \brief Test the material set_ambient method
TEST(material, set_ambient) {
bardrix::material material = bardrix::material(bardrix::color::red(), 0.1, 0.2, 0.3);
bardrix::material material = bardrix::material(0.1, 0.2, 0.3, 1);

material.set_ambient(0.5);
EXPECT_EQ(material.get_ambient(), 0.5);
Expand All @@ -63,48 +63,42 @@ TEST(material, set_ambient) {

/// \brief Test the material set_diffuse method
TEST(material, set_diffuse) {
bardrix::material material = bardrix::material(bardrix::color::red(), 0.1, 0.2, 0.3);
bardrix::material material = bardrix::material(0.1, 0.2, 0.3, 1);

material.set_diffuse(0.5);
EXPECT_EQ(material.get_diffuse(), 0.5);
EXPECT_EQ(material.get_specular(), 0.5);

material.set_diffuse(-0.5);
EXPECT_EQ(material.get_diffuse(), 0);
EXPECT_EQ(material.get_specular(), 1);

material.set_diffuse(1.5);
EXPECT_EQ(material.get_diffuse(), 1);
EXPECT_EQ(material.get_specular(), 0);
}

/// \brief Test the material set_specular method
TEST(material, set_specular) {
bardrix::material material = bardrix::material(bardrix::color::red(), 0.1, 0.2, 0.3);
bardrix::material material = bardrix::material(0.1, 0.2, 0.3, 1);

material.set_specular(0.5);
EXPECT_EQ(material.get_specular(), 0.5);
EXPECT_EQ(material.get_diffuse(), 0.5);

material.set_specular(-0.5);
EXPECT_EQ(material.get_specular(), 0);
EXPECT_EQ(material.get_diffuse(), 1);

material.set_specular(1.5);
EXPECT_EQ(material.get_specular(), 1);
EXPECT_EQ(material.get_diffuse(), 0);
}

/// \brief Test the material set_shininess method
TEST(material, set_shininess) {
bardrix::material material = bardrix::material(bardrix::color::red(), 0.1, 0.2, 0.3);
bardrix::material material = bardrix::material(0.1, 0.2, 0.3, 1);

material.set_shininess(0.5);
EXPECT_EQ(material.get_shininess(), 0.5);
EXPECT_EQ(material.get_shininess(), 1);

material.set_shininess(-0.5);
EXPECT_EQ(material.get_shininess(), 0);
EXPECT_EQ(material.get_shininess(), 1);

material.set_shininess(1.5);
EXPECT_EQ(material.get_shininess(), 1);
EXPECT_EQ(material.get_shininess(), 1.5);
}
49 changes: 42 additions & 7 deletions Bardrix_Tests/tests/vector3_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,52 @@ TEST(vector3, angle_orthogonal) {

/// \brief Test the reflection of a vector
TEST(vector3, reflection) {
bardrix::vector3 v1(1, 2, 3);
bardrix::vector3 normal(0, 0, 1);
bardrix::vector3 rotation_vector = {1, 2, 3};
bardrix::vector3 vector = {4, 5, 6};

std::optional<bardrix::vector3> result = v1.reflection(normal);
EXPECT_TRUE(result.has_value());
ASSERT_TRUE(bardrix::nearly_equal(result->length_squared(), 1));
EXPECT_EQ(result.value(), bardrix::vector3(1, 2, -3).normalized());
std::optional<bardrix::vector3> result = vector.reflection(rotation_vector);

ASSERT_TRUE(result.has_value());
ASSERT_EQ(*result, bardrix::vector3(0.5714, 4.1428, 7.7143));
}

/// \brief Test the reflection of a vector with the vector behind the normal and other degenerate cases
/// \brief Test the reflection of a vector with different values
TEST(vector3, reflection2) {
bardrix::vector3 rotation_vector = {1, 0,0};
bardrix::vector3 vector = {1, 2, 3};

std::optional<bardrix::vector3> result = vector.reflection(rotation_vector);

ASSERT_TRUE(result.has_value());
ASSERT_EQ(*result, bardrix::vector3(1, -2, -3));
}

/// \brief Test the reflection of a vector with vector being zero
TEST(vector3, reflection_degenerate) {
bardrix::vector3 rotation_vector = {1, 2, 3};
bardrix::vector3 vector = {0, 0, 0};

std::optional<bardrix::vector3> result = vector.reflection(rotation_vector);

EXPECT_FALSE(result.has_value());
}

/// \brief Test the reflection of a vector with rotation vector being zero
TEST(vector3, reflection_degenerate2) {
bardrix::vector3 rotation_vector = {0, 0, 0};
bardrix::vector3 vector = {4, 5, 6};

std::optional<bardrix::vector3> result = vector.reflection(rotation_vector);
ASSERT_FALSE(result.has_value());

rotation_vector = {-23,52,0};
result = vector.reflection(rotation_vector);
ASSERT_TRUE(result.has_value());
ASSERT_EQ(*result, bardrix::vector3(-6.3903, 0.40426, -6));
}

/// \brief Test the reflection of a vector with the vector behind the normal and other degenerate cases
TEST(vector3, reflection_degenerate3) {
bardrix::vector3 v1(1, 2, 3);
bardrix::vector3 normal(0, 0, -1);

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.27)
project(Bardrix)
set(BARDRIX_VERSION 0.2.3)
set(BARDRIX_VERSION 0.3.0)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
Expand Down
Loading

0 comments on commit f4e27cc

Please sign in to comment.