diff --git a/include/fennec/lang/types.h b/include/fennec/lang/types.h index 5d3a5f7..fee7b55 100644 --- a/include/fennec/lang/types.h +++ b/include/fennec/lang/types.h @@ -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 - using void_t = void; + class undefined_t; ///< \brief undefined class for SFINAE + template 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; ///< \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; - - /// - /// \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; - - /// - /// \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; ///< \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; /// @} } diff --git a/include/fennec/math/common.h b/include/fennec/math/common.h index ca037f0..ecd814b 100644 --- a/include/fennec/math/common.h +++ b/include/fennec/math/common.h @@ -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$.

-/// \details We can express this as,

-/// \f$\text{abs}(x)=\left|x\right|\f$.

-/// -/// \param x input value -template -constexpr genType abs(genType x) - { return ::abs(x); } - - -// Vector Specializations ---------------------------------------------------------------------------------------------- - -template -constexpr vector abs(const vector& x) - { return vector(fennec::abs(x[i]) ...); } - - // Sign ================================================================================================================ @@ -328,6 +306,28 @@ template constexpr vector sign(const vector& x) { return vector(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$.

+/// \details We can express this as,

+/// \f$\text{abs}(x)=\left|x\right|\f$.

+/// +/// \param x input value +template +constexpr genType abs(genType x) + { return x * fennec::sign(x); } + + +// Vector Specializations ---------------------------------------------------------------------------------------------- + +template +constexpr vector abs(const vector& x) + { return vector(fennec::abs(x[i]) ...); } + /// @} @@ -776,6 +776,10 @@ constexpr genType min(genType x, genType y) // Vector Specializations ---------------------------------------------------------------------------------------------- +template +constexpr vector min(genType x, const vector& y) + { return vector(fennec::min(x, y[i]) ...); } + template constexpr vector min(const vector& x, genType y) { return vector(fennec::min(x[i], y) ...); } @@ -804,6 +808,10 @@ constexpr genType max(genType x, genType y) // Vector Specializations ---------------------------------------------------------------------------------------------- +template +constexpr vector max(genType x, const vector& y) + { return vector(fennec::max(x, y[i]) ...); } + template constexpr vector max(const vector& x, genType y) { return vector(fennec::max(x[i], y) ...); } diff --git a/include/fennec/math/ext/constants.h b/include/fennec/math/ext/constants.h index ed6ee12..982ad2f 100644 --- a/include/fennec/math/ext/constants.h +++ b/include/fennec/math/ext/constants.h @@ -178,29 +178,109 @@ /// \copydetails fennec::half_pi /// ///
+/// \ref fennec::three_halves_pi "genType three_halves_pi()" +/// +/// \copydetails fennec::three_halves_pi +/// +///
/// \ref fennec::third_pi "genType third_pi()" /// /// \copydetails fennec::third_pi /// ///
+/// \ref fennec::two_thirds_pi "genType two_thirds_pi()" +/// +/// \copydetails fennec::two_thirds_pi +/// +///
+/// \ref fennec::four_thirds_pi "genType four_thirds_pi()" +/// +/// \copydetails fennec::four_thirds_pi +/// +///
+/// \ref fennec::five_thirds_pi "genType five_thirds_pi()" +/// +/// \copydetails fennec::five_thirds_pi +/// +///
/// \ref fennec::quarter_pi "genType quarter_pi()" /// /// \copydetails fennec::quarter_pi /// ///
+/// \ref fennec::three_quarters_pi "genType three_quarters_pi()" +/// +/// \copydetails fennec::three_quarters_pi +/// +///
+/// \ref fennec::five_quarters_pi "genType five_quarters_pi()" +/// +/// \copydetails fennec::five_quarters_pi +/// +///
+/// \ref fennec::seven_quarters_pi "genType seven_quarters_pi()" +/// +/// \copydetails fennec::seven_quarters_pi +/// +///
/// \ref fennec::fifth_pi "genType fifth_pi()" /// /// \copydetails fennec::fifth_pi /// ///
+/// \ref fennec::two_fifths_pi "genType two_fifths_pi()" +/// +/// \copydetails fennec::two_fifths_pi +/// +///
+/// \ref fennec::three_fifths_pi "genType three_fifths_pi()" +/// +/// \copydetails fennec::three_fifths_pi +/// +///
+/// \ref fennec::four_fifths_pi "genType four_fifths_pi()" +/// +/// \copydetails fennec::four_fifths_pi +/// +///
+/// \ref fennec::six_fifths_pi "genType six_fifths_pi()" +/// +/// \copydetails fennec::six_fifths_pi +/// +///
+/// \ref fennec::seven_fifths_pi "genType seven_fifths_pi()" +/// +/// \copydetails fennec::seven_fifths_pi +/// +///
+/// \ref fennec::eight_fifths_pi "genType eight_fifths_pi()" +/// +/// \copydetails fennec::eight_fifths_pi +/// +///
+/// \ref fennec::eight_fifths_pi "genType eight_fifths_pi()" +/// +/// \copydetails fennec::nine_fifths_pi +/// +///
/// \ref fennec::sixth_pi "genType sixth_pi()" /// /// \copydetails fennec::sixth_pi /// ///
-/// \ref fennec::two_thirds_pi "genType two_thirds_pi()" +/// \ref fennec::five_sixths_pi "genType five_sixths_pi()" /// -/// \copydetails fennec::two_thirds_pi +/// \copydetails fennec::five_sixths_pi +/// +///
+/// \ref fennec::seven_sixths_pi "genType seven_sixths_pi()" +/// +/// \copydetails fennec::seven_sixths_pi +/// +///
+/// \ref fennec::eleven_sixths_pi "genType eleven_sixths_pi()" +/// +/// \copydetails fennec::eleven_sixths_pi /// /// Reciprocals of π ///
@@ -494,12 +574,36 @@ template constexpr genType three_pi() { return 9.424777960769 template 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 constexpr genType e_sq() { return 7.38905 template constexpr genType e_cb() { return 20.08553692318766774092852965458171789698790783855415; } ///< \returns The value of \f$e^3\f$ with the highest precision for \f$genType\f$ template constexpr genType sqrt_e() { return 1.64872127070012814684865078781416357165377610071014; } ///< \returns The value of \f$\sqrt{e}\f$ with the highest precision for \f$genType\f$ template 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 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 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 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$ diff --git a/include/fennec/math/geometric.h b/include/fennec/math/geometric.h index 951a187..6fb7c38 100644 --- a/include/fennec/math/geometric.h +++ b/include/fennec/math/geometric.h @@ -270,9 +270,12 @@ constexpr vector reflect(const vector& I, const ve /// \param eta the ratio of indices of refraction template constexpr vector refract(const vector& I, const vector& 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(0); + return eta * I - N * (eta * ndi + fennec::sqrt(k)); +} } diff --git a/include/fennec/math/relational.h b/include/fennec/math/relational.h index d7061d3..b35809c 100644 --- a/include/fennec/math/relational.h +++ b/include/fennec/math/relational.h @@ -208,7 +208,7 @@ constexpr genBType all(const vector& x) /// \returns the component-wise logical complement of \f$x\f$. /// \param x the boolean vector to inverse template -constexpr genBType operator not(const vector& x) +constexpr vector operator not(const vector& x) { return vector((!x[i]) ...); } } diff --git a/include/fennec/math/vector.h b/include/fennec/math/vector.h index 040ddff..2036f45 100644 --- a/include/fennec/math/vector.h +++ b/include/fennec/math/vector.h @@ -144,74 +144,25 @@ template using tvec4 = vec; -/// -/// \brief A two-component boolean \ref fennec_math_vector "vector" -using bvec2 = tvec2; +using bvec2 = tvec2; ///< \brief A two-component boolean \ref fennec_math_vector "vector" +using bvec3 = tvec3; ///< \brief A three-component boolean \ref fennec_math_vector "vector" +using bvec4 = tvec4; ///< \brief A four-component boolean \ref fennec_math_vector "vector" -/// -/// \brief A three-component boolean \ref fennec_math_vector "vector" -using bvec3 = tvec3; +using ivec2 = tvec2; ///< \brief A two-component signed integer \ref fennec_math_vector "vector" +using ivec3 = tvec3; ///< \brief A three-component signed integer \ref fennec_math_vector "vector" +using ivec4 = tvec4; ///< \brief A four-component signed integer \ref fennec_math_vector "vector" -/// -/// \brief A four-component boolean \ref fennec_math_vector "vector" -using bvec4 = tvec4; +using uvec2 = tvec2; ///< \brief A two-component unsigned integer \ref fennec_math_vector "vector" +using uvec3 = tvec3; ///< \brief A three-component unsigned integer \ref fennec_math_vector "vector" +using uvec4 = tvec4; ///< \brief A four-component unsigned integer \ref fennec_math_vector "vector" +using vec2 = tvec2; ///< \brief A two-component single-precision floating-point \ref fennec_math_vector "vector" +using vec3 = tvec3; ///< \brief A three-component single-precision floating-point \ref fennec_math_vector "vector" +using vec4 = tvec4; ///< \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; - -/// -/// \brief A three-component signed integer \ref fennec_math_vector "vector" -using ivec3 = tvec3; - -/// -/// \brief A four-component signed integer \ref fennec_math_vector "vector" -using ivec4 = tvec4; - - - -/// -/// \brief A two-component unsigned integer \ref fennec_math_vector "vector" -using uvec2 = tvec2; - -/// -/// \brief A three-component unsigned integer \ref fennec_math_vector "vector" -using uvec3 = tvec3; - -/// -/// \brief A four-component unsigned integer \ref fennec_math_vector "vector" -using uvec4 = tvec4; - - - -/// -/// \brief A two-component single-precision floating-point \ref fennec_math_vector "vector" -using vec2 = tvec2; - -/// -/// \brief A three-component single-precision floating-point \ref fennec_math_vector "vector" -using vec3 = tvec3; - -/// -/// \brief A four-component single-precision floating-point \ref fennec_math_vector "vector" -using vec4 = tvec4; - - - -/// -/// \brief A two-component double-precision floating-point \ref fennec_math_vector "vector" -using dvec2 = tvec2; - -/// -/// \brief A three-component double-precision floating-point \ref fennec_math_vector "vector" -using dvec3 = tvec3; - -/// -/// \brief A four-component double-precision floating-point \ref fennec_math_vector "vector" -using dvec4 = tvec4; - +using dvec2 = tvec2; ///< \brief A two-component double-precision floating-point \ref fennec_math_vector "vector" +using dvec3 = tvec3; ///< \brief A three-component double-precision floating-point \ref fennec_math_vector "vector" +using dvec4 = tvec4; ///< \brief A four-component double-precision floating-point \ref fennec_math_vector "vector" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 580e25f..75ea123 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 diff --git a/test/main.cpp b/test/main.cpp index a3d9e5e..52cc0e8 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -18,12 +18,12 @@ #include -#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 **) { diff --git a/test/test.h b/test/test.h index baaa609..37ef480 100644 --- a/test/test.h +++ b/test/test.h @@ -35,6 +35,7 @@ namespace fennec namespace test { +// Helper for printing vectors template inline std::ostream& operator<<(std::ostream& os, const vector& v) { @@ -44,15 +45,7 @@ inline std::ostream& operator<<(std::ostream& os, const vector -inline std::ostream& operator<<(std::ostream& os, vector&& v) -{ - os << "< "; - ((os << v[IndicesV] << " "), ...); - os << ">"; - return os; -} - +// Helper for printing matrices template inline std::ostream& operator<<(std::ostream& os, const matrix& m) { @@ -65,30 +58,41 @@ inline std::ostream& operator<<(std::ostream& os, const matrix -inline bool operator<=(const vector& lhs, const vector& rhs) -{ - return fennec::all(fennec::lessThanEqual(lhs, rhs)); -} - +// Core test function template 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) - passed = fennec::abs(expected - result) <= numeric_limits::epsilon(); - else if constexpr(is_vector_v && not(is_bool_v)) - passed = fennec::abs(expected - result) <= numeric_limits::epsilon(); - else - passed = result == expected; + bool passed = false; + + // Check scalar arithmetic values + if constexpr(is_arithmetic_v) + { + passed = result == expected; + passed |= fennec::abs(expected - result) <= numeric_limits::epsilon(); + } + // Check non-boolean vector values + else if constexpr(is_vector_v && not(is_bool_v)) + { + passed = result == expected; + passed |= fennec::all(fennec::lessThanEqual(fennec::abs(expected - result), ResultT(numeric_limits::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); } diff --git a/test/tests/math/test_common.h b/test/tests/math/test_common.h index cb4c0e1..61ce8b3 100644 --- a/test/tests/math/test_common.h +++ b/test/tests/math/test_common.h @@ -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)); @@ -165,14 +167,12 @@ inline void fennec_test_math_common() fennec_test_spacer(1); fennec_test_run(min(2.0f, 1.0f), 1.0f); - fennec_test_run(min(-fennec::numeric_limits::infinity(), 0.0f), -fennec::numeric_limits::infinity()); - fennec_test_run(min( fennec::numeric_limits::quiet_NaN(), -1.0f), -1.0f); + fennec_test_run(min(-fennec::numeric_limits::infinity(), 0.0f), -fennec::numeric_limits::infinity()); fennec_test_spacer(1); fennec_test_run(max(2.0f, 1.0f), 2.0f); - fennec_test_run(max(-fennec::numeric_limits::infinity(), 0.0f), 0.0f); - fennec_test_run(max( fennec::numeric_limits::quiet_NaN(), -1.0f), -1.0f); + fennec_test_run(max(-fennec::numeric_limits::infinity(), 0.0f), 0.0f); fennec_test_spacer(1); diff --git a/test/tests/math/test_exponential.h b/test/tests/math/test_exponential.h index 3d3b5e9..646de5b 100644 --- a/test/tests/math/test_exponential.h +++ b/test/tests/math/test_exponential.h @@ -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); diff --git a/test/tests/math/test_geometric.h b/test/tests/math/test_geometric.h index 59d4f67..94e3c23 100644 --- a/test/tests/math/test_geometric.h +++ b/test/tests/math/test_geometric.h @@ -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); + } } diff --git a/test/tests/math/test_matrix.h b/test/tests/math/test_matrix.h index d0a7c04..04fd859 100644 --- a/test/tests/math/test_matrix.h +++ b/test/tests/math/test_matrix.h @@ -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); } } diff --git a/test/tests/math/test_relational.h b/test/tests/math/test_relational.h new file mode 100644 index 0000000..5a18d4a --- /dev/null +++ b/test/tests/math/test_relational.h @@ -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 . +// ===================================================================================================================== + +#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 diff --git a/test/tests/math/test_trigonometric.h b/test/tests/math/test_trigonometric.h new file mode 100644 index 0000000..d2da391 --- /dev/null +++ b/test/tests/math/test_trigonometric.h @@ -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 . +// ===================================================================================================================== + +#ifndef FENNEC_TEST_MATH_TRIGONOMETRIC_H +#define FENNEC_TEST_MATH_TRIGONOMETRIC_H +#include +#include + +#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()); + fennec_test_run(fennec::radians( 90.0f), fennec::half_pi()); + fennec_test_run(fennec::radians(180.0f), fennec::pi()); + fennec_test_run(fennec::radians(270.0f), fennec::three_halves_pi()); + fennec_test_run(fennec::radians(360.0f), fennec::two_pi()); + + fennec_test_spacer(1); + + fennec_test_run(fennec::degrees(fennec::quarter_pi()), 45.0f); + fennec_test_run(fennec::degrees(fennec::half_pi()), 90.0f); + fennec_test_run(fennec::degrees(fennec::pi()), 180.0f); + fennec_test_run(fennec::degrees(fennec::three_halves_pi()), 270.0f); + fennec_test_run(fennec::degrees(fennec::two_pi()), 360.0f); + + fennec_test_spacer(2); + + + + fennec_test_section("trig functions"); + + fennec_test_spacer(1); + + fennec_test_run(fennec::sin(fennec::sixth_pi()), one_half()); + fennec_test_run(fennec::cos(fennec::sixth_pi()), sqrt_three() / 2.0f); + fennec_test_run(fennec::tan(fennec::sixth_pi()), sqrt_three() / 3.0f); + + fennec_test_spacer(1); + + fennec_test_run(fennec::asin(one_half()), fennec::sixth_pi()); + fennec_test_run(fennec::acos(sqrt_three() / 2.0f), fennec::sixth_pi()); + fennec_test_run(fennec::atan(sqrt_three() / 3.0f), fennec::sixth_pi()); + + + fennec_test_spacer(2); + + + fennec_test_run(fennec::sin(fennec::quarter_pi()), sqrt_two() / 2.0f); + fennec_test_run(fennec::cos(fennec::quarter_pi()), sqrt_two() / 2.0f); + fennec_test_run(fennec::tan(fennec::quarter_pi()), 1.0f); + + fennec_test_spacer(1); + + fennec_test_run(fennec::asin(sqrt_two() / 2.0f), fennec::quarter_pi()); + fennec_test_run(fennec::acos(sqrt_two() / 2.0f), fennec::quarter_pi()); + fennec_test_run(fennec::atan(1.0f), fennec::quarter_pi()); + + 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() - fennec::one_over_e()) / 2.0f); + fennec_test_run(fennec::cosh(1.0f), (fennec::e() + fennec::one_over_e()) / 2.0f); + fennec_test_run(fennec::tanh(1.0f), ((fennec::e_raised_two() - 1) / (fennec::e_raised_two() + 1))); + + fennec_test_spacer(1); + + fennec_test_run(fennec::asinh((fennec::e() - fennec::one_over_e()) / 2.0f), 1.0f); + fennec_test_run(fennec::acosh((fennec::e() + fennec::one_over_e()) / 2.0f), 1.0f); + fennec_test_run(fennec::atanh(((fennec::e_raised_two() - 1) / (fennec::e_raised_two() + 1))), 1.0f); + + + fennec_test_spacer(2); + + +} + +} + +} + +#endif // FENNEC_TEST_MATH_TRIGONOMETRIC_H diff --git a/test/tests/test_math.h b/test/tests/test_math.h index 52453b8..c856566 100644 --- a/test/tests/test_math.h +++ b/test/tests/test_math.h @@ -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); } }