- Finished unit tests for core math library

- Adjusted formatting
This commit is contained in:
2025-07-02 10:17:35 -04:00
parent 516d9f4977
commit 9010650ceb
16 changed files with 446 additions and 259 deletions

View File

@@ -220,61 +220,27 @@ namespace fennec
/// \name Basic Types
/// @{
///
/// \brief A conditional type
using bool_t = bool;
using bool_t = bool; ///< \brief A conditional type
///
/// \brief A type capable of holding an ascii value
using char_t = char;
using char_t = char; ///< \brief A type capable of holding an ascii value
using schar_t = signed char; ///< \brief A type with the size of a char, capable of holding a signed 8-bit integer
using uchar_t = unsigned char; ///< \brief A type with the size of a char, capable of holding an unsigned 8-bit integer
///
/// \brief A type with the size of a char, capable of holding a signed 8-bit integer
using schar_t = signed char;
using short_t = signed short; ///< \brief A signed short type, capable of holding signed 16-bit integer
using ushort_t = unsigned short; ///< \brief An unsigned short type, capable of holding an unsigned signed 16-bit integer
///
/// \brief A type with the size of a char, capable of holding an unsigned 8-bit integer
using uchar_t = unsigned char;
using int_t = signed int; ///< \brief A signed integer type, size varies by implementation, but typically 32-bit
using uint_t = unsigned int; ///< \brief An unsigned integer type, size varies by implementation, but typically 32-bit
///
/// \brief A signed short type, capable of holding signed 16-bit integer
using short_t = signed short;
using long_t = signed long; ///< \brief A signed integer type, with a size of at least 32-bits
using ulong_t = unsigned long; ///< \brief An unsigned integer type, with a size of at least 32-bits
///
/// \brief An unsigned short type, capable of holding an unsigned signed 16-bit integer
using ushort_t = unsigned short;
using llong_t = signed long long; ///< \brief A signed integer type, with a size of 64-bits
using ullong_t = unsigned long long; ///< \brief An unsigned integer type, with a size of 64-bits
///
/// \brief A signed integer type, size varies by implementation, but typically 32-bit
using int_t = signed int;
using float_t = float; ///< \brief A single-precision floating-point type, typically with a size of 32-bits
using double_t = double; ///< \brief A double-precision floating-point type, typically with a size of 64-bits
///
/// \brief An unsigned integer type, size varies by implementation, but typically 32-bit
using uint_t = unsigned int;
///
/// \brief A signed integer type, with a size of at least 32-bits
using long_t = signed long;
///
/// \brief An unsigned integer type, with a size of at least 32-bits
using ulong_t = unsigned long;
///
/// \brief A signed integer type, with a size of 64-bits
using llong_t = signed long long;
///
/// \brief An unsigned integer type, with a size of 64-bits
using ullong_t = unsigned long long;
///
/// \brief A single-precision floating-point type, typically with a size of 32-bits
using float_t = float;
///
/// \brief A double-point type, typically with a size of 64-bits
using double_t = double;
/// @}
@@ -283,42 +249,17 @@ namespace fennec
/// \name Special Types
/// @{
///
/// \brief Null Pointer Type
using nullptr_t = decltype(nullptr);
///
/// \brief Signed Integer Capable of Holding a Pointer to void
using intptr_t = intptr_t;
using nullptr_t = decltype(nullptr); ///< \brief Null Pointer Type
using intptr_t = intptr_t; ///< \brief Signed Integer Capable of Holding a Pointer to void
using uintptr_t = uintptr_t; ///< \brief Unsigned Integer Capable of Holding a Pointer to void
using intmax_t = __INTMAX_TYPE__; ///< \brief Maximum Width Signed Integer Type
using uintmax_t = __UINTMAX_TYPE__; ///< \brief Maximum Width Unsigned Integer Type
using size_t = __SIZE_TYPE__; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers
///
/// \brief Unsigned Integer Capable of Holding a Pointer to void
using uintptr_t = uintptr_t;
///
/// \brief Maximum Width Signed Integer Type
using intmax_t = __INTMAX_TYPE__;
///
/// \brief Maximum Width Unsigned Integer Type
using uintmax_t = __UINTMAX_TYPE__;
///
/// \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
using size_t = __SIZE_TYPE__;
///
/// \brief Signed Integer Type Returned by the Subtraction of two Pointers
using ptrdiff_t = __PTRDIFF_TYPE__;
///
/// \brief undefined class for SFINAE
class undefined_t;
///
/// \brief Void type used for SFINAE
template<typename...>
using void_t = void;
class undefined_t; ///< \brief undefined class for SFINAE
template<typename...> using void_t = void; ///< \brief Void type used for SFINAE
/// @}
}
@@ -334,45 +275,15 @@ namespace fennec
/// \name Sized Integer Types
/// @{
///
/// \brief Signed 8-bit integer
using int8_t = schar_t;
using int8_t = schar_t; ///< \brief Signed 8-bit integer
using int16_t = short_t; ///< \brief Signed 16-bit integer
using int32_t = conditional_t<sizeof(int_t) == 4, int_t, long_t>; ///< \brief Signed 32-bit integer
using int64_t = llong_t; ///< \brief Signed 64-bit integer
///
/// \brief Signed 16-bit integer
using int16_t = short_t;
///
/// \brief Signed 32-bit integer
using int32_t = conditional_t<sizeof(int_t) == 4, int_t, long_t>;
///
/// \brief Signed signed 64-bit integer
using int64_t = llong_t;
/// @}
///
/// \name Sized Unsigned Integer Types
/// @{
///
/// \brief Unsigned 8-bit integer
using uint8_t = uchar_t;
///
/// \brief Unsigned 16-bit integer
using uint16_t = ushort_t;
///
/// \brief Unsigned 32-bit integer
using uint32_t = conditional_t<sizeof(uint_t) == 4, uint_t, ulong_t>;
///
/// \brief Unsigned 64-bit integer
using uint64_t = ullong_t;
using uint8_t = uchar_t; ///< \brief Unsigned 8-bit integer
using uint16_t = ushort_t; ///< \brief Unsigned 16-bit integer
using uint32_t = conditional_t<sizeof(uint_t) == 4, uint_t, ulong_t>; ///< \brief Unsigned 32-bit integer
using uint64_t = ullong_t; ///< \brief Unsigned 64-bit integer
/// @}
@@ -382,13 +293,10 @@ namespace fennec
/// \name Sized Floating-Point Types
/// @{
///
/// \brief A single-precision floating-point scalar
using float32_t = float_t;
using float16_t = _Float16; ///< \brief A half-precision floating-point scalar
using float32_t = _Float32; ///< \brief A single-precision floating-point scalar
using float64_t = _Float64; ///< \brief A double-precision floating-point scalar
///
/// \brief A double-precision floating-point scalar
using float64_t = double_t;
/// @}
}

View File

@@ -284,28 +284,6 @@ namespace fennec
/// @{
// Absolute Value ======================================================================================================
///
/// \brief Returns \f$x\f$ if \f$x \ge 0\f$, otherwise it returns \f$-x\f$
///
/// \returns \f$x\f$ if \f$x \ge 0\f$, otherwise it returns \f$-x\f$. <br> <br>
/// \details We can express this as, <br> <br>
/// \f$\text{abs}(x)=\left|x\right|\f$.<br> <br>
///
/// \param x input value
template<typename genType>
constexpr genType abs(genType x)
{ return ::abs(x); }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> abs(const vector<genType, i...>& x)
{ return vector<genType, i...>(fennec::abs(x[i]) ...); }
// Sign ================================================================================================================
@@ -328,6 +306,28 @@ template<typename genType, size_t...i>
constexpr vector<genType, i...> sign(const vector<genType, i...>& x)
{ return vector<genType, i...>(fennec::sign(x[i]) ...); }
// Absolute Value ======================================================================================================
///
/// \brief Returns \f$x\f$ if \f$x \ge 0\f$, otherwise it returns \f$-x\f$
///
/// \returns \f$x\f$ if \f$x \ge 0\f$, otherwise it returns \f$-x\f$. <br> <br>
/// \details We can express this as, <br> <br>
/// \f$\text{abs}(x)=\left|x\right|\f$.<br> <br>
///
/// \param x input value
template<typename genType>
constexpr genType abs(genType x)
{ return x * fennec::sign(x); }
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> abs(const vector<genType, i...>& x)
{ return vector<genType, i...>(fennec::abs(x[i]) ...); }
/// @}
@@ -776,6 +776,10 @@ constexpr genType min(genType x, genType y)
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(genType x, const vector<genType, i...>& y)
{ return vector<genType, i...>(fennec::min(x, y[i]) ...); }
template<typename genType, size_t...i>
constexpr vector<genType, i...> min(const vector<genType, i...>& x, genType y)
{ return vector<genType, i...>(fennec::min(x[i], y) ...); }
@@ -804,6 +808,10 @@ constexpr genType max(genType x, genType y)
// Vector Specializations ----------------------------------------------------------------------------------------------
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(genType x, const vector<genType, i...>& y)
{ return vector<genType, i...>(fennec::max(x, y[i]) ...); }
template<typename genType, size_t...i>
constexpr vector<genType, i...> max(const vector<genType, i...>& x, genType y)
{ return vector<genType, i...>(fennec::max(x[i], y) ...); }

View File

@@ -178,29 +178,109 @@
/// \copydetails fennec::half_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::three_halves_pi "genType three_halves_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::three_halves_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::third_pi "genType third_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::third_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::two_thirds_pi "genType two_thirds_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::two_thirds_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::four_thirds_pi "genType four_thirds_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::four_thirds_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::five_thirds_pi "genType five_thirds_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::five_thirds_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::quarter_pi "genType quarter_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::quarter_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::three_quarters_pi "genType three_quarters_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::three_quarters_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::five_quarters_pi "genType five_quarters_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::five_quarters_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::seven_quarters_pi "genType seven_quarters_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::seven_quarters_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::fifth_pi "genType fifth_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::fifth_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::two_fifths_pi "genType two_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::two_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::three_fifths_pi "genType three_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::three_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::four_fifths_pi "genType four_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::four_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::six_fifths_pi "genType six_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::six_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::seven_fifths_pi "genType seven_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::seven_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::eight_fifths_pi "genType eight_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::eight_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::eight_fifths_pi "genType eight_fifths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::nine_fifths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::sixth_pi "genType sixth_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::sixth_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::two_thirds_pi "genType two_thirds_pi<genType>()"
/// \ref fennec::five_sixths_pi "genType five_sixths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::two_thirds_pi
/// \copydetails fennec::five_sixths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::seven_sixths_pi "genType seven_sixths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::seven_sixths_pi
///
/// <tr><td width="50%" style="vertical-align: top"> <br>
/// \ref fennec::eleven_sixths_pi "genType eleven_sixths_pi<genType>()"
/// <td width="50%" style="vertical-align: top">
/// \copydetails fennec::eleven_sixths_pi
///
/// <tr><th colspan=2 style="text-align: center;">Reciprocals of π
/// <tr><td width="50%" style="vertical-align: top"> <br>
@@ -494,12 +574,36 @@ template<typename genType> constexpr genType three_pi() { return 9.424777960769
template<typename genType> constexpr genType four_pi() { return 12.56637061435917295385057353311801153678867759750042; } ///< \returns The value of \f$4\pi\f$ with the highest precision for \f$genType\f$
// Fractions of Pi
template<typename genType> constexpr genType half_pi() { return 1.57079632679489661923132169163975144209858469968755; } ///< \returns The value of \f$\frac{\pi}{2}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType three_halves_pi() { return 4.71238898038468985769396507491925432629575409906265; } ///< \returns The value of \f$\frac{3\pi}{2}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType third_pi() { return 1.04719755119659774615421446109316762806572313312503; } ///< \returns The value of \f$\frac{\pi}{3}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType quarter_pi() { return 0.78539816339744830961566084581987572104929234984377; } ///< \returns The value of \f$\frac{\pi}{4}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType fifth_pi() { return 0.62831853071795864769252867665590057683943387987502; } ///< \returns The value of \f$\frac{\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType sixth_pi() { return 0.52359877559829887307710723054658381403286156656251; } ///< \returns The value of \f$\frac{\pi}{6}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType two_thirds_pi() { return 2.09439510239319549230842892218633525613144626625007; } ///< \returns The value of \f$\frac{2\pi}{3}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType four_thirds_pi() { return 4.18879020478639098461685784437267051226289253250014; } ///< \returns The value of \f$\frac{4\pi}{3}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType five_thirds_pi() { return 5.23598775598298873077107230546583814032861566562517; } ///< \returns The value of \f$\frac{5\pi}{3}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType quarter_pi() { return 0.78539816339744830961566084581987572104929234984377; } ///< \returns The value of \f$\frac{\pi}{4}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType three_quarters_pi() { return 2.35619449019234492884698253745962716314787704953132; } ///< \returns The value of \f$\frac{3\pi}{4}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType five_quarters_pi() { return 3.92699081698724154807830422909937860524646174921888; } ///< \returns The value of \f$\frac{5\pi}{4}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType seven_quarters_pi() { return 5.49778714378213816730962592073913004734504644890643; } ///< \returns The value of \f$\frac{7\pi}{4}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType fifth_pi() { return 0.62831853071795864769252867665590057683943387987502; } ///< \returns The value of \f$\frac{\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType two_fifths_pi() { return 1.25663706143591729538505735331180115367886775975004; } ///< \returns The value of \f$\frac{2\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType three_fifths_pi() { return 1.88495559215387594307758602996770173051830163962506; } ///< \returns The value of \f$\frac{3\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType four_fifths_pi() { return 2.51327412287183459077011470662360230735773551950008; } ///< \returns The value of \f$\frac{4\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType six_fifths_pi() { return 3.76991118430775188615517205993540346103660327925012; } ///< \returns The value of \f$\frac{6\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType seven_fifths_pi() { return 4.39822971502571053384770073659130403787603715912514; } ///< \returns The value of \f$\frac{7\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType eight_fifths_pi() { return 5.02654824574366918154022941324720461471547103900016; } ///< \returns The value of \f$\frac{8\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType nine_fifths_pi() { return 5.65486677646162782923275808990310519155490491887519; } ///< \returns The value of \f$\frac{9\pi}{5}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType sixth_pi() { return 0.52359877559829887307710723054658381403286156656251; } ///< \returns The value of \f$\frac{\pi}{6}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType five_sixths_pi() { return 2.61799387799149436538553615273291907016430783281258; } ///< \returns The value of \f$\frac{5\pi}{6}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType seven_sixths_pi() { return 3.66519142918809211153975061382608669823003096593762; } ///< \returns The value of \f$\frac{7\pi}{6}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType eleven_sixths_pi() { return 5.75958653158128760384817953601242195436147723218769; } ///< \returns The value of \f$\frac{11\pi}{6}\f$ with the highest precision for \f$genType\f$
// Reciprocals of Pi
template<typename genType> constexpr genType one_over_pi() { return 0.31830988618379067153776752674502872406891929148091; } ///< \returns The value of \f$\frac{1}{\pi}\f$ with the highest precision for \f$genType\f$
@@ -529,6 +633,7 @@ template<typename genType> constexpr genType e_sq() { return 7.38905
template<typename genType> constexpr genType e_cb() { return 20.08553692318766774092852965458171789698790783855415; } ///< \returns The value of \f$e^3\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType sqrt_e() { return 1.64872127070012814684865078781416357165377610071014; } ///< \returns The value of \f$\sqrt{e}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType one_over_sqrt_e() { return 0.60653065971263342360379953499118045344191813548718; } ///< \returns The value of \f$\frac{1}{\sqrt{e}}\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType e_raised_two() { return 7.38905609893065022723042746057500781318031557055184; } ///< \returns The value of \f$e^e\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType e_raised_e() { return 15.15426224147926418976043027262991190552854853685613; } ///< \returns The value of \f$e^e\f$ with the highest precision for \f$genType\f$
template<typename genType> constexpr genType e_raised_neg_e() { return 0.065988035845312537076790187596846424938577048252796; } ///< \returns The value of \f$e^-e\f$ with the highest precision for \f$genType\f$

View File

@@ -270,9 +270,12 @@ constexpr vector<genType, i...> reflect(const vector<genType, i...>& I, const ve
/// \param eta the ratio of indices of refraction
template<typename genType, size_t...i>
constexpr vector<genType, i...> refract(const vector<genType, i...>& I, const vector<genType, i...>& N, genType eta)
{ genType ndi = fennec::dot(N, I);
{
genType ndi = fennec::dot(N, I);
genType k = 1.0 - eta * eta * (1.0 - ndi * ndi);
return fennec::max(0.0, eta * I - N * (eta * ndi + fennec::sqrt(k))); }
if (k < 0) return vector<genType, i...>(0);
return eta * I - N * (eta * ndi + fennec::sqrt(k));
}
}

View File

@@ -208,7 +208,7 @@ constexpr genBType all(const vector<genBType, i...>& x)
/// \returns the component-wise logical complement of \f$x\f$.
/// \param x the boolean vector to inverse
template<typename genBType = bool_t, size_t...i>
constexpr genBType operator not(const vector<genBType, i...>& x)
constexpr vector<genBType, i...> operator not(const vector<genBType, i...>& x)
{ return vector<genBType, i...>((!x[i]) ...); }
}

View File

@@ -144,74 +144,25 @@ template<typename ScalarT> using tvec4 = vec<ScalarT, 4>;
///
/// \brief A two-component boolean \ref fennec_math_vector "vector"
using bvec2 = tvec2<bool_t>;
using bvec2 = tvec2<bool_t>; ///< \brief A two-component boolean \ref fennec_math_vector "vector"
using bvec3 = tvec3<bool_t>; ///< \brief A three-component boolean \ref fennec_math_vector "vector"
using bvec4 = tvec4<bool_t>; ///< \brief A four-component boolean \ref fennec_math_vector "vector"
///
/// \brief A three-component boolean \ref fennec_math_vector "vector"
using bvec3 = tvec3<bool_t>;
using ivec2 = tvec2<int32_t>; ///< \brief A two-component signed integer \ref fennec_math_vector "vector"
using ivec3 = tvec3<int32_t>; ///< \brief A three-component signed integer \ref fennec_math_vector "vector"
using ivec4 = tvec4<int32_t>; ///< \brief A four-component signed integer \ref fennec_math_vector "vector"
///
/// \brief A four-component boolean \ref fennec_math_vector "vector"
using bvec4 = tvec4<bool_t>;
using uvec2 = tvec2<uint32_t>; ///< \brief A two-component unsigned integer \ref fennec_math_vector "vector"
using uvec3 = tvec3<uint32_t>; ///< \brief A three-component unsigned integer \ref fennec_math_vector "vector"
using uvec4 = tvec4<uint32_t>; ///< \brief A four-component unsigned integer \ref fennec_math_vector "vector"
using vec2 = tvec2<float_t>; ///< \brief A two-component single-precision floating-point \ref fennec_math_vector "vector"
using vec3 = tvec3<float_t>; ///< \brief A three-component single-precision floating-point \ref fennec_math_vector "vector"
using vec4 = tvec4<float_t>; ///< \brief A four-component single-precision floating-point \ref fennec_math_vector "vector"
///
/// \brief A two-component signed integer \ref fennec_math_vector "vector"
using ivec2 = tvec2<int32_t>;
///
/// \brief A three-component signed integer \ref fennec_math_vector "vector"
using ivec3 = tvec3<int32_t>;
///
/// \brief A four-component signed integer \ref fennec_math_vector "vector"
using ivec4 = tvec4<int32_t>;
///
/// \brief A two-component unsigned integer \ref fennec_math_vector "vector"
using uvec2 = tvec2<uint32_t>;
///
/// \brief A three-component unsigned integer \ref fennec_math_vector "vector"
using uvec3 = tvec3<uint32_t>;
///
/// \brief A four-component unsigned integer \ref fennec_math_vector "vector"
using uvec4 = tvec4<uint32_t>;
///
/// \brief A two-component single-precision floating-point \ref fennec_math_vector "vector"
using vec2 = tvec2<float32_t>;
///
/// \brief A three-component single-precision floating-point \ref fennec_math_vector "vector"
using vec3 = tvec3<float32_t>;
///
/// \brief A four-component single-precision floating-point \ref fennec_math_vector "vector"
using vec4 = tvec4<float32_t>;
///
/// \brief A two-component double-precision floating-point \ref fennec_math_vector "vector"
using dvec2 = tvec2<float64_t>;
///
/// \brief A three-component double-precision floating-point \ref fennec_math_vector "vector"
using dvec3 = tvec3<float64_t>;
///
/// \brief A four-component double-precision floating-point \ref fennec_math_vector "vector"
using dvec4 = tvec4<float64_t>;
using dvec2 = tvec2<double_t>; ///< \brief A two-component double-precision floating-point \ref fennec_math_vector "vector"
using dvec3 = tvec3<double_t>; ///< \brief A three-component double-precision floating-point \ref fennec_math_vector "vector"
using dvec4 = tvec4<double_t>; ///< \brief A four-component double-precision floating-point \ref fennec_math_vector "vector"

View File

@@ -17,6 +17,8 @@ add_executable(fennec-test main.cpp
tests/lang/test_sequences.h
tests/math/test_common.h
tests/math/test_exponential.h
tests/math/test_relational.h
tests/math/test_trigonometric.h
)
target_link_libraries(fennec-test PRIVATE

View File

@@ -18,12 +18,12 @@
#include <iostream>
#include "test.h"
#include "tests/test_lang.h"
#include "tests/test_math.h"
#include "tests/test_memory.h"
#include "test.h"
int main(int, char **)
{

View File

@@ -35,6 +35,7 @@ namespace fennec
namespace test
{
// Helper for printing vectors
template<typename ScalarT, size_t...IndicesV>
inline std::ostream& operator<<(std::ostream& os, const vector<ScalarT, IndicesV...>& v)
{
@@ -44,15 +45,7 @@ inline std::ostream& operator<<(std::ostream& os, const vector<ScalarT, IndicesV
return os;
}
template<typename ScalarT, size_t...IndicesV>
inline std::ostream& operator<<(std::ostream& os, vector<ScalarT, IndicesV...>&& v)
{
os << "< ";
((os << v[IndicesV] << " "), ...);
os << ">";
return os;
}
// Helper for printing matrices
template<typename ScalarT, size_t RowsV, size_t...ColIndicesV>
inline std::ostream& operator<<(std::ostream& os, const matrix<ScalarT, RowsV, ColIndicesV...>& m)
{
@@ -65,30 +58,41 @@ inline std::ostream& operator<<(std::ostream& os, const matrix<ScalarT, RowsV, C
return os;
}
template<typename ScalarT, size_t...IndicesV>
inline bool operator<=(const vector<ScalarT, IndicesV...>& lhs, const vector<ScalarT, IndicesV...>& rhs)
{
return fennec::all(fennec::lessThanEqual(lhs, rhs));
}
// Core test function
template<typename ResultT>
inline void __fennec_test_run(const std::string& expression, const ResultT result, const ResultT expected)
{
// Print out the expression as a string and the resulting value
std::cout << std::boolalpha;
std::cout << '\t' << expression << " = " << result;
bool passed = false;
if constexpr(is_arithmetic_v<ResultT>)
passed = fennec::abs(expected - result) <= numeric_limits<ResultT>::epsilon();
else if constexpr(is_vector_v<ResultT> && not(is_bool_v<typename ResultT::scalar_t>))
passed = fennec::abs(expected - result) <= numeric_limits<ResultT>::epsilon();
else
passed = result == expected;
bool passed = false;
// Check scalar arithmetic values
if constexpr(is_arithmetic_v<ResultT>)
{
passed = result == expected;
passed |= fennec::abs(expected - result) <= numeric_limits<ResultT>::epsilon();
}
// Check non-boolean vector values
else if constexpr(is_vector_v<ResultT> && not(is_bool_v<typename ResultT::scalar_t>))
{
passed = result == expected;
passed |= fennec::all(fennec::lessThanEqual(fennec::abs(expected - result), ResultT(numeric_limits<typename ResultT::scalar_t>::epsilon())));
}
// Base Case, simple comparison
else
{
passed = result == expected;
}
// Print out expected when failed
if (not passed)
std::cout << ", expected " << expected;
std::cout << std::endl;
// Assert to halt and get some debug info
assert(passed);
}

View File

@@ -40,6 +40,8 @@ inline void fennec_test_math_common()
fennec_test_run(fennec::abs( 1.0), 1.0);
fennec_test_run(fennec::abs(-1.0), 1.0);
fennec_test_run(fennec::abs(vec2(1.0f, -1.0f)), vec2(1.0f));
fennec_test_spacer(1);
fennec_test_run(fennec::sign(vec2( 1, -2)), vec2( 1, -1));
@@ -166,13 +168,11 @@ inline void fennec_test_math_common()
fennec_test_run(min(2.0f, 1.0f), 1.0f);
fennec_test_run(min(-fennec::numeric_limits<float>::infinity(), 0.0f), -fennec::numeric_limits<float>::infinity());
fennec_test_run(min( fennec::numeric_limits<float>::quiet_NaN(), -1.0f), -1.0f);
fennec_test_spacer(1);
fennec_test_run(max(2.0f, 1.0f), 2.0f);
fennec_test_run(max(-fennec::numeric_limits<float>::infinity(), 0.0f), 0.0f);
fennec_test_run(max( fennec::numeric_limits<float>::quiet_NaN(), -1.0f), -1.0f);
fennec_test_spacer(1);

View File

@@ -32,8 +32,6 @@ namespace test
inline void fennec_test_math_exponential()
{
fennec_test_spacer(1);
fennec_test_run(fennec::pow(1.0f, 2.0f), 1.0f);
fennec_test_run(fennec::pow(2.0f, 0.0f), 1.0f);
fennec_test_run(fennec::pow(2.0f, 1.0f), 2.0f);

View File

@@ -68,6 +68,18 @@ inline void fennec_test_math_geometric()
fennec_test_run(fennec::normalize(vec3(1, 1, 1)), vec3(sqrt(3.0f) / 3.0f, sqrt(3.0f) / 3.0f, sqrt(3.0f) / 3.0f));
fennec_test_run(fennec::normalize(vec4(1, 1, 1, 1)), vec4(0.5f, 0.5f, 0.5f, 0.5f));
fennec_test_spacer(1);
fennec_test_run(fennec::faceforward(vec3(1, 0, 0), vec3(-1, 0, 0), vec3(1, 0, 0)), vec3(-1, 0, 0));
fennec_test_run(fennec::faceforward(vec3(1, 0, 0), vec3(-1, 0, 0), vec3(-1, 0, 0)), vec3( 1, 0, 0));
fennec_test_spacer(1);
fennec_test_run(fennec::reflect(vec2(1, -1), vec2(0, 1)), vec2(1, 1));
fennec_test_run(fennec::refract(vec2(1, -1), vec2(0, 1), 1/1.33f), vec2(0.7518797, -1));
fennec_test_spacer(2);
}
}

View File

@@ -120,7 +120,7 @@ inline void fennec_test_math_matrix()
fennec_test_header("matrix equality operators");
fennec_test_section("matrix equality operators");
fennec_test_spacer(1);
@@ -138,7 +138,7 @@ inline void fennec_test_math_matrix()
fennec_test_header("matrix constructors");
fennec_test_section("matrix constructors");
fennec_test_spacer(1);
@@ -156,7 +156,7 @@ inline void fennec_test_math_matrix()
fennec_test_header("matrix-scalar operators");
fennec_test_section("matrix-scalar operators");
fennec_test_spacer(1);
@@ -169,7 +169,7 @@ inline void fennec_test_math_matrix()
fennec_test_header("matrix-vector operators");
fennec_test_section("matrix-vector operators");
fennec_test_spacer(1);
@@ -187,7 +187,7 @@ inline void fennec_test_math_matrix()
fennec_test_header("matrix-matrix operators");
fennec_test_section("matrix-matrix operators");
fennec_test_spacer(1);
@@ -315,11 +315,13 @@ inline void fennec_test_math_matrix()
fennec_test_section("inverse");
fennec_test_spacer(2);
fennec_test_spacer(1);
fennec_test_run(fennec::inverse(mat2(1, 2, 3, 4)), mat2(-2, 1, 1.5, -0.5));
fennec_test_run(fennec::inverse(mat3(1, 2, 3, 0, 1, 4, 5, 6, 0)), mat3(-24, 18, 5, 20, -15, -4, -5, 4, 1));
fennec_test_run(fennec::inverse(mat4(2, 1, -3, 4, -1, 0, 2, 5, 3, 2, 1, 0, 4, -2, 3, 1)), (1.0f / 414.0f) * mat4(36, -39, 33, 51, -18, 31, 133, -83, -72, 55, 49, 13, 36, 53, -13, 5));
fennec_test_spacer(2);
}
}

View File

@@ -0,0 +1,56 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_TEST_MATH_RELATIONAL_H
#define FENNEC_TEST_MATH_RELATIONAL_H
#include "../../test.h"
namespace fennec
{
namespace test
{
inline void fennec_test_math_relational()
{
fennec_test_run(fennec::lessThan(vec3(3, 2, 1), vec3(1, 2, 3)), bvec3(false, false, true));
fennec_test_run(fennec::lessThanEqual(vec3(3, 2, 1), vec3(1, 2, 3)), bvec3(false, true, true));
fennec_test_spacer(1);
fennec_test_run(fennec::greaterThan(vec3(3, 2, 1), vec3(1, 2, 3)), bvec3(true, false, false));
fennec_test_run(fennec::greaterThanEqual(vec3(3, 2, 1), vec3(1, 2, 3)), bvec3(true, true, false));
fennec_test_spacer(1);
fennec_test_run(fennec::equal(vec3(3, 2, 1), vec3(1, 2, 3)), bvec3(false, true, false));
fennec_test_run(fennec::notEqual(vec3(3, 2, 1), vec3(1, 2, 3)), bvec3(true, false, true));
fennec_test_spacer(1);
fennec_test_run(not(bvec3(true, false, true)), bvec3(false, true, false));
fennec_test_run(fennec::all(bvec3(true, true, true)), true);
fennec_test_spacer(2);
}
}
}
#endif // FENNEC_TEST_MATH_RELATIONAL_H

View File

@@ -0,0 +1,126 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_TEST_MATH_TRIGONOMETRIC_H
#define FENNEC_TEST_MATH_TRIGONOMETRIC_H
#include <fennec/math/trigonometric.h>
#include <fennec/math/ext/constants.h>
#include "../../test.h"
namespace fennec
{
namespace test
{
inline void fennec_test_math_trigonometric()
{
fennec_test_section("angle conversions");
fennec_test_spacer(1);
fennec_test_run(fennec::radians( 45.0f), fennec::quarter_pi<float>());
fennec_test_run(fennec::radians( 90.0f), fennec::half_pi<float>());
fennec_test_run(fennec::radians(180.0f), fennec::pi<float>());
fennec_test_run(fennec::radians(270.0f), fennec::three_halves_pi<float>());
fennec_test_run(fennec::radians(360.0f), fennec::two_pi<float>());
fennec_test_spacer(1);
fennec_test_run(fennec::degrees(fennec::quarter_pi<float>()), 45.0f);
fennec_test_run(fennec::degrees(fennec::half_pi<float>()), 90.0f);
fennec_test_run(fennec::degrees(fennec::pi<float>()), 180.0f);
fennec_test_run(fennec::degrees(fennec::three_halves_pi<float>()), 270.0f);
fennec_test_run(fennec::degrees(fennec::two_pi<float>()), 360.0f);
fennec_test_spacer(2);
fennec_test_section("trig functions");
fennec_test_spacer(1);
fennec_test_run(fennec::sin(fennec::sixth_pi<float>()), one_half<float>());
fennec_test_run(fennec::cos(fennec::sixth_pi<float>()), sqrt_three<float>() / 2.0f);
fennec_test_run(fennec::tan(fennec::sixth_pi<float>()), sqrt_three<float>() / 3.0f);
fennec_test_spacer(1);
fennec_test_run(fennec::asin(one_half<float>()), fennec::sixth_pi<float>());
fennec_test_run(fennec::acos(sqrt_three<float>() / 2.0f), fennec::sixth_pi<float>());
fennec_test_run(fennec::atan(sqrt_three<float>() / 3.0f), fennec::sixth_pi<float>());
fennec_test_spacer(2);
fennec_test_run(fennec::sin(fennec::quarter_pi<float>()), sqrt_two<float>() / 2.0f);
fennec_test_run(fennec::cos(fennec::quarter_pi<float>()), sqrt_two<float>() / 2.0f);
fennec_test_run(fennec::tan(fennec::quarter_pi<float>()), 1.0f);
fennec_test_spacer(1);
fennec_test_run(fennec::asin(sqrt_two<float>() / 2.0f), fennec::quarter_pi<float>());
fennec_test_run(fennec::acos(sqrt_two<float>() / 2.0f), fennec::quarter_pi<float>());
fennec_test_run(fennec::atan(1.0f), fennec::quarter_pi<float>());
fennec_test_spacer(2);
fennec_test_section("hyperbolic functions");
fennec_test_spacer(1);
fennec_test_run(fennec::sinh(0.0f), 0.0f);
fennec_test_run(fennec::cosh(0.0f), 1.0f);
fennec_test_run(fennec::tanh(0.0f), 0.0f);
fennec_test_spacer(1);
fennec_test_run(fennec::asinh(0.0f), 0.0f);
fennec_test_run(fennec::acosh(1.0f), 0.0f);
fennec_test_run(fennec::atanh(0.0f), 0.0f);
fennec_test_spacer(2);
fennec_test_run(fennec::sinh(1.0f), (fennec::e<float>() - fennec::one_over_e<float>()) / 2.0f);
fennec_test_run(fennec::cosh(1.0f), (fennec::e<float>() + fennec::one_over_e<float>()) / 2.0f);
fennec_test_run(fennec::tanh(1.0f), ((fennec::e_raised_two<float>() - 1) / (fennec::e_raised_two<float>() + 1)));
fennec_test_spacer(1);
fennec_test_run(fennec::asinh((fennec::e<float>() - fennec::one_over_e<float>()) / 2.0f), 1.0f);
fennec_test_run(fennec::acosh((fennec::e<float>() + fennec::one_over_e<float>()) / 2.0f), 1.0f);
fennec_test_run(fennec::atanh(((fennec::e_raised_two<float>() - 1) / (fennec::e_raised_two<float>() + 1))), 1.0f);
fennec_test_spacer(2);
}
}
}
#endif // FENNEC_TEST_MATH_TRIGONOMETRIC_H

View File

@@ -26,6 +26,8 @@
#include "math/test_common.h"
#include "math/test_exponential.h"
#include "math/test_geometric.h"
#include "math/test_relational.h"
#include "math/test_trigonometric.h"
namespace fennec
{
@@ -64,6 +66,16 @@ inline void fennec_test_math()
fennec_test_spacer(2);
fennec_test_math_geometric();
fennec_test_spacer(3);
fennec_test_subheader("relational tests");
fennec_test_spacer(2);
fennec_test_math_relational();
fennec_test_spacer(3);
fennec_test_subheader("trigonometric tests");
fennec_test_spacer(2);
fennec_test_math_trigonometric();
fennec_test_spacer(3);
}
}