diff --git a/core/maths/vector.hpp b/core/maths/vector.hpp index 44ae857..1b7d209 100644 --- a/core/maths/vector.hpp +++ b/core/maths/vector.hpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace SpaceEngine { @@ -12,45 +13,58 @@ class Vector { std::array data; // Constructors - constexpr Vector() noexcept = default; - constexpr explicit Vector(T val) noexcept; - template - constexpr explicit Vector(Args&&... args) noexcept; + constexpr Vector() = default; + constexpr explicit Vector(T val); + template > + constexpr explicit Vector(Args&&... args); + + // Dimensionality adjustements + constexpr explicit Vector(const Vector& vec); + constexpr Vector(const Vector& vec, T val); // Accessors for x, y, z, w. - constexpr const T& x() const noexcept; - constexpr T& x() noexcept; - constexpr const T& y() const noexcept; - constexpr T& y() noexcept; - constexpr const T& z() const noexcept; - constexpr T& z() noexcept; - constexpr const T& w() const noexcept; - constexpr T& w() noexcept; + constexpr const T& x() const; + constexpr T& x(); + constexpr const T& y() const; + constexpr T& y(); + constexpr const T& z() const; + constexpr T& z(); + constexpr const T& w() const; + constexpr T& w(); // Operations. - constexpr Vector operator-() const noexcept; - constexpr Vector operator+(const Vector& vec) const noexcept; - constexpr Vector operator-(const Vector& vec) const noexcept; - constexpr Vector operator*(const Vector& vec) const noexcept; - constexpr Vector operator*(T val) const noexcept; - constexpr Vector operator/(const Vector& vec) const noexcept; - constexpr Vector operator/(T val) const noexcept; + constexpr Vector operator-() const; + constexpr Vector operator+(const Vector& vec) const; + constexpr Vector operator+(T val) const; + constexpr Vector operator-(const Vector& vec) const; + constexpr Vector operator-(T val) const; + constexpr Vector operator*(const Vector& vec) const; + constexpr Vector operator*(T val) const; + constexpr Vector operator/(const Vector& vec) const; + constexpr Vector operator/(T val) const; // Assignement operations. - constexpr Vector& operator+=(const Vector& vec) noexcept; - constexpr Vector& operator-=(const Vector& vec) noexcept; - constexpr Vector& operator*=(const Vector& vec) noexcept; - constexpr Vector& operator*=(T val) noexcept; - constexpr Vector& operator/=(const Vector& vec) noexcept; - constexpr Vector& operator/=(T val) noexcept; + constexpr Vector& operator+=(const Vector& vec); + constexpr Vector& operator+=(T val); + constexpr Vector& operator-=(const Vector& vec); + constexpr Vector& operator-=(T val); + constexpr Vector& operator*=(const Vector& vec); + constexpr Vector& operator*=(T val); + constexpr Vector& operator/=(const Vector& vec); + constexpr Vector& operator/=(T val); // Access operators. - constexpr const T& operator[](std::size_t index) const noexcept; - constexpr T& operator[](std::size_t index) noexcept; + constexpr const T& operator[](std::size_t index) const; + constexpr T& operator[](std::size_t index); // Equality operators. - constexpr bool operator==(const Vector& vec) const noexcept; - constexpr bool operator!=(const Vector& vec) const noexcept; + constexpr bool operator==(const Vector& vec) const; + constexpr bool operator!=(const Vector& vec) const; + + // Utils + // TODO : Add following functions + // constexpr float dot(const Vector& vec) const; + // constexpr Vector cross(const Vector& vec) const; }; // Aliases @@ -59,10 +73,18 @@ template using Vec2 = Vector; template using Vec3 = Vector; template using Vec4 = Vector; +using Vec2b = Vec2; +using Vec3b = Vec3; +using Vec4b = Vec4; + using Vec2i = Vec2; using Vec3i = Vec3; using Vec4i = Vec4; +using Vec2u = Vec2; +using Vec3u = Vec3; +using Vec4u = Vec4; + using Vec2f = Vec2; using Vec3f = Vec3; using Vec4f = Vec4; diff --git a/core/maths/vector.inl b/core/maths/vector.inl index 5a75f83..05f57bf 100644 --- a/core/maths/vector.inl +++ b/core/maths/vector.inl @@ -3,64 +3,79 @@ namespace SpaceEngine { template -constexpr Vector::Vector(T val) noexcept { +constexpr Vector::Vector(T val) { data.fill(val); } template -template -constexpr Vector::Vector(Args&&... args) noexcept : data{{std::forward(args)...}} {} +template +constexpr Vector::Vector(Args&&... args) : data{ static_cast(args)... } {} template -constexpr const T& Vector::x() const noexcept { +constexpr Vector::Vector(const Vector& vec) { + for (std::size_t i = 0; i < N; ++i) { + data[i] = vec.data[i]; + } +} + +template +constexpr Vector::Vector(const Vector& vec, T val) { + for (std::size_t i = 0; i < N - 1; ++i) { + data[i] = vec.data[i]; + } + data[N - 1] = val; +} + +template +constexpr const T& Vector::x() const { static_assert(N >= 1, "Vector does not have an X component."); return data[0]; } template -constexpr T& Vector::x() noexcept { +constexpr T& Vector::x() { static_assert(N >= 1, "Vector does not have an X component."); return data[0]; } template -constexpr const T& Vector::y() const noexcept { +constexpr const T& Vector::y() const { static_assert(N >= 2, "Vector does not have a Y component."); return data[1]; } template -constexpr T& Vector::y() noexcept { +constexpr T& Vector::y() { static_assert(N >= 2, "Vector does not have a Y component."); return data[1]; } template -constexpr const T& Vector::z() const noexcept { +constexpr const T& Vector::z() const { static_assert(N >= 3, "Vector does not have a Z component."); return data[2]; } template -constexpr T& Vector::z() noexcept { +constexpr T& Vector::z() { static_assert(N >= 3, "Vector does not have a Z component."); return data[2]; } template -constexpr const T& Vector::w() const noexcept { +constexpr const T& Vector::w() const { static_assert(N >= 4, "Vector does not have a W component."); return data[3]; } template -constexpr T& Vector::w() noexcept { +constexpr T& Vector::w() { static_assert(N >= 4, "Vector does not have a W component."); return data[3]; } template -constexpr Vector Vector::operator-() const noexcept { +constexpr Vector Vector::operator-() const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = -data[i]; @@ -69,7 +84,7 @@ constexpr Vector Vector::operator-() const noexcept { } template -constexpr Vector Vector::operator+(const Vector& vec) const noexcept { +constexpr Vector Vector::operator+(const Vector& vec) const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = data[i] + vec.data[i]; @@ -78,7 +93,16 @@ constexpr Vector Vector::operator+(const Vector& vec) const no } template -constexpr Vector Vector::operator-(const Vector& vec) const noexcept { +constexpr Vector Vector::operator+(T val) const { + Vector result; + for (std::size_t i = 0; i < N; ++i) { + result.data[i] = data[i] + val; + } + return result; +} + +template +constexpr Vector Vector::operator-(const Vector& vec) const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = data[i] - vec.data[i]; @@ -87,7 +111,16 @@ constexpr Vector Vector::operator-(const Vector& vec) const no } template -constexpr Vector Vector::operator*(T val) const noexcept { +constexpr Vector Vector::operator-(T val) const { + Vector result; + for (std::size_t i = 0; i < N; ++i) { + result.data[i] = data[i] - val; + } + return result; +} + +template +constexpr Vector Vector::operator*(T val) const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = data[i] * val; @@ -96,7 +129,7 @@ constexpr Vector Vector::operator*(T val) const noexcept { } template -constexpr Vector Vector::operator*(const Vector& vec) const noexcept { +constexpr Vector Vector::operator*(const Vector& vec) const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = data[i] * vec.data[i]; @@ -105,7 +138,7 @@ constexpr Vector Vector::operator*(const Vector& vec) const no } template -constexpr Vector Vector::operator/(T val) const noexcept { +constexpr Vector Vector::operator/(T val) const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = data[i] / val; @@ -114,7 +147,7 @@ constexpr Vector Vector::operator/(T val) const noexcept { } template -constexpr Vector Vector::operator/(const Vector& vec) const noexcept { +constexpr Vector Vector::operator/(const Vector& vec) const { Vector result; for (std::size_t i = 0; i < N; ++i) { result.data[i] = data[i] / vec.data[i]; @@ -123,7 +156,7 @@ constexpr Vector Vector::operator/(const Vector& vec) const no } template -constexpr Vector& Vector::operator+=(const Vector& vec) noexcept { +constexpr Vector& Vector::operator+=(const Vector& vec) { for (std::size_t i = 0; i < N; ++i) { data[i] += vec.data[i]; } @@ -131,7 +164,15 @@ constexpr Vector& Vector::operator+=(const Vector& vec) noexce } template -constexpr Vector& Vector::operator-=(const Vector& vec) noexcept { +constexpr Vector& Vector::operator+=(T val) { + for (std::size_t i = 0; i < N; ++i) { + data[i] += val; + } + return *this; +} + +template +constexpr Vector& Vector::operator-=(const Vector& vec) { for (std::size_t i = 0; i < N; ++i) { data[i] -= vec.data[i]; } @@ -139,7 +180,15 @@ constexpr Vector& Vector::operator-=(const Vector& vec) noexce } template -constexpr Vector& Vector::operator*=(T val) noexcept { +constexpr Vector& Vector::operator-=(T val) { + for (std::size_t i = 0; i < N; ++i) { + data[i] -= val; + } + return *this; +} + +template +constexpr Vector& Vector::operator*=(T val) { for (std::size_t i = 0; i < N; ++i) { data[i] *= val; } @@ -147,7 +196,7 @@ constexpr Vector& Vector::operator*=(T val) noexcept { } template -constexpr Vector& Vector::operator*=(const Vector& vec) noexcept { +constexpr Vector& Vector::operator*=(const Vector& vec) { for (std::size_t i = 0; i < N; ++i) { data[i] *= vec.data[i]; } @@ -155,7 +204,7 @@ constexpr Vector& Vector::operator*=(const Vector& vec) noexce } template -constexpr Vector& Vector::operator/=(T val) noexcept { +constexpr Vector& Vector::operator/=(T val) { for (std::size_t i = 0; i < N; ++i) { data[i] /= val; } @@ -163,7 +212,7 @@ constexpr Vector& Vector::operator/=(T val) noexcept { } template -constexpr Vector& Vector::operator/=(const Vector& vec) noexcept { +constexpr Vector& Vector::operator/=(const Vector& vec) { for (std::size_t i = 0; i < N; ++i) { data[i] /= vec.data[i]; } @@ -171,17 +220,17 @@ constexpr Vector& Vector::operator/=(const Vector& vec) noexce } template -constexpr const T& Vector::operator[](std::size_t index) const noexcept { +constexpr const T& Vector::operator[](std::size_t index) const { return data[index]; } template -constexpr T& Vector::operator[](std::size_t index) noexcept { +constexpr T& Vector::operator[](std::size_t index) { return data[index]; } template -constexpr bool Vector::operator==(const Vector& vec) const noexcept { +constexpr bool Vector::operator==(const Vector& vec) const { for (std::size_t i = 0; i < N; ++i) { if (data[i] != vec.data[i]) { return false; @@ -191,7 +240,7 @@ constexpr bool Vector::operator==(const Vector& vec) const noexcept } template -constexpr bool Vector::operator!=(const Vector& vec) const noexcept { +constexpr bool Vector::operator!=(const Vector& vec) const { return !(*this == vec); } @@ -206,5 +255,4 @@ std::ostream& operator<<(std::ostream& stream, const Vector& vec) { return stream; } - } diff --git a/tests/test_vector2.cpp b/tests/test_vector2.cpp index 601d94e..1b0feac 100644 --- a/tests/test_vector2.cpp +++ b/tests/test_vector2.cpp @@ -1,56 +1,80 @@ #include "test.hpp" #include "maths/vector.hpp" -using SpaceEngine::Vec2f; // Using the float specialization for 2D vectors +using namespace SpaceEngine; int testVector2() { Vec2f vec1(1.0f, 2.0f); Vec2f vec2(3.0f, 5.0f); - // Test addition + // Vector/Vector addition auto add_result = vec1 + vec2; - custom_assert(add_result.x() == 4.0f && add_result.y() == 7.0f, "Vec2f addition failed"); + custom_assert(add_result.x() == 4.0f && add_result.y() == 7.0f, "Vec2f vector addition failed"); - // Test subtraction + // Vector/Scalar addition + custom_assert(vec1 + 3 == Vec2f(4.0f, 5.0f), "Vec2f scalar addition failed") + + // Vector/Vector subtraction auto sub_result = vec1 - vec2; custom_assert(sub_result.x() == -2.0f && sub_result.y() == -3.0f, "Vec2f subtraction failed"); - // Test multiplication by a scalar + // Vector/Scalar subtraction + custom_assert(vec2 - 3 == Vec2f(0.0f, 2.0f), "Vec2f scalar subtraction failed") + + // Multiplication by a scalar auto mul_result_scalar = vec1 * 2.0f; custom_assert(mul_result_scalar.x() == 2.0f && mul_result_scalar.y() == 4.0f, "Vec2f scalar multiplication failed"); - // Test division by a scalar + // Division by a scalar auto div_result_scalar = vec1 / 2.0f; custom_assert(div_result_scalar.x() == 0.5f && div_result_scalar.y() == 1.0f, "Vec2f scalar division failed"); - // Test += with a vector + // += with a vector Vec2f vec3 = vec1; vec3 += vec2; custom_assert(vec3.x() == 4.0f && vec3.y() == 7.0f, "Vec2f += failed"); - // Test -= with a vector + // += with a scalar + vec3 = vec1; + vec3 += 2.0f; + custom_assert(vec3.x() == 3.0f && vec3.y() == 4.0f, "Vec2f += scalar failed"); + + // -= with a vector vec3 = vec1; vec3 -= vec2; custom_assert(vec3.x() == -2.0f && vec3.y() == -3.0f, "Vec2f -= failed"); - // Test *= with a scalar + // -= with a scalar + vec3 = vec1; + vec3 -= 2.0f; + custom_assert(vec3.x() == -1.0f && vec3.y() == 0.0f, "Vec2f -= scalar failed"); + + // *= with a scalar vec3 = vec1; vec3 *= 2.0f; custom_assert(vec3.x() == 2.0f && vec3.y() == 4.0f, "Vec2f *= failed"); - // Test /= with a scalar + // /= with a scalar vec3 = vec1; vec3 /= 2.0f; custom_assert(vec3.x() == 0.5f && vec3.y() == 1.0f, "Vec2f /= failed"); - // Test operator[] + // operator[] custom_assert(vec1[0] == 1.0f && vec1[1] == 2.0f, "Vec2f operator[] failed"); - // Test equality + // equality Vec2f vec4(1.0f, 2.0f); custom_assert(vec1 == vec4, "Vec2f equality failed"); - // Test inequality + // inequality custom_assert(vec1 != vec2, "Vec2f inequality failed"); + + // extension + Vec3f extendedVec = Vec3f(vec1, 3.0f); + custom_assert(extendedVec.z() == 3.0f, "Vec2f to Vec3fextension failed"); + + // truncation + Vec2f truncatedVec = Vec2f(extendedVec); + custom_assert(truncatedVec.x() == extendedVec.x() && truncatedVec.y() == extendedVec.y(), "Vec3f to Vec2f truncation failed"); return 0; } diff --git a/tests/test_vector3.cpp b/tests/test_vector3.cpp index 5518094..f8cbdb7 100644 --- a/tests/test_vector3.cpp +++ b/tests/test_vector3.cpp @@ -2,6 +2,7 @@ #include "maths/vector.hpp" using SpaceEngine::Vec3f; +using SpaceEngine::Vec4f; int testVector3() { Vec3f vec1(1.0f, 2.0f, 3.0f); @@ -52,5 +53,13 @@ int testVector3() { // Test inequality custom_assert(vec1 != vec2, "Vec3f inequality failed"); + + // // Extend Vec3f to Vec4f + // Vec4f extendedVec = Vec4f(vec1, 4.0f); + // custom_assert(extendedVec.w() == 4.0f, "Vec3f to Vec4f extension failed"); + + // // Truncate Vec4f back to Vec3f + // Vec3f truncatedVec = Vec3f(extendedVec); + // custom_assert(truncatedVec.x() == extendedVec.x() && truncatedVec.y() == extendedVec.y() && truncatedVec.z() == extendedVec.z(), "Vec4f to Vec3f truncation failed"); return 0; }