diff options
-rw-r--r-- | Client/Source/Phy2DLite/Settings.h | 56 | ||||
-rw-r--r-- | Client/Source/Phy2DLite/Tests/test_p2d.cpp | 4 | ||||
-rw-r--r-- | Client/ThirdParty/fpm/include/fpm/fixed.hpp | 311 | ||||
-rw-r--r-- | Client/ThirdParty/fpm/include/fpm/math.hpp | 2 |
4 files changed, 234 insertions, 139 deletions
diff --git a/Client/Source/Phy2DLite/Settings.h b/Client/Source/Phy2DLite/Settings.h index e976e26..e50646c 100644 --- a/Client/Source/Phy2DLite/Settings.h +++ b/Client/Source/Phy2DLite/Settings.h @@ -4,13 +4,59 @@ #define NUMBER_LIBFIX 2
#define NUMBER_FPM 3
-#define NUMBER_ALIAS NUMBER_LIBFIX
+#define NUMBER_ALIAS NUMBER_FPM
#if NUMBER_ALIAS == NUMBER_LIBFIX
#include "libfixmath/libfixmath/fixmath.h"
#elif NUMBER_ALIAS == NUMBER_FPM
#include "fpm/include/fpm/fixed.hpp"
#include "fpm/include/fpm/math.hpp"
+ +template <typename T> +struct Limits {}; + +template <> +struct Limits<fpm::fixed_16_16> +{ + static constexpr bool is_signed() noexcept { return true; } + static constexpr int digits() noexcept { return 31; } + static constexpr int max_digits10() noexcept { return 5 + 5; } + static constexpr int min_exponent() noexcept { return -15; } + static constexpr int max_exponent() noexcept { return 15; } + static constexpr int min_exponent10() noexcept { return -4; } + static constexpr int max_exponent10() noexcept { return 4; } + static constexpr fpm::fixed_16_16 min() noexcept { return fpm::fixed_16_16::from_raw_value(-2147483647 - 1); } + static constexpr fpm::fixed_16_16 max() noexcept { return fpm::fixed_16_16::from_raw_value(2147483647); } +}; + +template <> +struct Limits<fpm::fixed_24_8> +{ + static constexpr bool is_signed() noexcept { return true; } + static constexpr int digits() noexcept { return 31; } + static constexpr int max_digits10() noexcept { return 7 + 3; } + static constexpr int min_exponent() noexcept { return -7; } + static constexpr int max_exponent() noexcept { return 23; } + static constexpr int min_exponent10() noexcept { return -2; } + static constexpr int max_exponent10() noexcept { return 6; } + static constexpr fpm::fixed_24_8 min() noexcept { return fpm::fixed_24_8::from_raw_value(-2147483647 - 1); } + static constexpr fpm::fixed_24_8 max() noexcept { return fpm::fixed_24_8::from_raw_value(2147483647); } +}; + +template <> +struct Limits<fpm::fixed_8_24> +{ + static constexpr bool is_signed() noexcept { return true; } + static constexpr int digits() noexcept { return 31; } + static constexpr int max_digits10() noexcept { return 3 + 8; } + static constexpr int min_exponent() noexcept { return -23; } + static constexpr int max_exponent() noexcept { return 7; } + static constexpr int min_exponent10() noexcept { return -7; } + static constexpr int max_exponent10() noexcept { return 2; } + static constexpr fpm::fixed_8_24 min() noexcept { return fpm::fixed_8_24::from_raw_value(-2147483647 - 1); } + static constexpr fpm::fixed_8_24 max() noexcept { return fpm::fixed_8_24::from_raw_value(2147483647); } +}; +
#endif
namespace Phy2D
@@ -38,13 +84,13 @@ typedef Fix16 number; #elif NUMBER_ALIAS == NUMBER_FPM
typedef fpm::fixed_16_16 number;
-#define NUMBER_MAX (number::max())
-#define NUMBER_MIN (number::min())
+#define NUMBER_MAX (Limits<number>::max())
+#define NUMBER_MIN (Limits<number>::min())
#define SQRT(a) (fpm::sqrt((a)))
#define SIN(a) (fpm::sin((a)))
#define COS(a) (fpm::cos((a)))
+#define PI (number::pi())
#endif
-}
-
+}
\ No newline at end of file diff --git a/Client/Source/Phy2DLite/Tests/test_p2d.cpp b/Client/Source/Phy2DLite/Tests/test_p2d.cpp index a668301..69737f6 100644 --- a/Client/Source/Phy2DLite/Tests/test_p2d.cpp +++ b/Client/Source/Phy2DLite/Tests/test_p2d.cpp @@ -292,7 +292,7 @@ static void Demo7(Body* b, Joint* j) float dampingRatio = 0.7f; // frequency in radians - float omega = (number)2.0f * fix16_pi * frequencyHz; + float omega = (number)2.0f * PI * frequencyHz; // damping coefficient float d = 2.0f * mass * dampingRatio * omega; @@ -418,7 +418,7 @@ static void Demo9(Body* b, Joint* j) float dampingRatio = 0.7f; // frequency in radians - float omega = (number) 2.0f * fix16_pi * frequencyHz; + float omega = (number) 2.0f * PI * frequencyHz; // damping coefficient float d = 2.0f * mass * dampingRatio * omega; diff --git a/Client/ThirdParty/fpm/include/fpm/fixed.hpp b/Client/ThirdParty/fpm/include/fpm/fixed.hpp index 9feff29..b900dd0 100644 --- a/Client/ThirdParty/fpm/include/fpm/fixed.hpp +++ b/Client/ThirdParty/fpm/include/fpm/fixed.hpp @@ -36,34 +36,34 @@ namespace fpm // Converts an integral number to the fixed-point type. // Like static_cast, this truncates bits that don't fit. template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> - constexpr inline explicit fixed(T val) noexcept + constexpr inline /*explicit*/ fixed(T val) noexcept : m_value(static_cast<BaseType>(val * FRACTION_MULT)) {} // Converts an floating-point number to the fixed-point type. // Like static_cast, this truncates bits that don't fit. template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> - constexpr inline explicit fixed(T val) noexcept + constexpr inline /*explicit*/ fixed(T val) noexcept : m_value(static_cast<BaseType>((val >= 0.0) ? (val * FRACTION_MULT + T{0.5}) : (val * FRACTION_MULT - T{0.5}))) {} // Constructs from another fixed-point type with possibly different underlying representation. // Like static_cast, this truncates bits that don't fit. template <typename B, typename I, unsigned int F> - constexpr inline explicit fixed(fixed<B,I,F> val) noexcept + constexpr inline /*explicit*/ fixed(fixed<B,I,F> val) noexcept : m_value(from_fixed_point<F>(val.raw_value()).raw_value()) {} // Explicit conversion to a floating-point type template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> - constexpr inline explicit operator T() const noexcept + constexpr inline /*explicit*/ operator T() const noexcept { return static_cast<T>(m_value) / FRACTION_MULT; } // Explicit conversion to an integral type template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> - constexpr inline explicit operator T() const noexcept + constexpr inline /*explicit*/ operator T() const noexcept { return static_cast<T>(m_value / FRACTION_MULT); } @@ -248,6 +248,13 @@ namespace fpm return fixed<B, I, F>(x) *= y; } + template <typename B, typename I, unsigned int F, typename T> + constexpr inline fixed<B, I, F> operator*(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return fixed<B, I, F>(x) *= r; + } + template <typename B, typename I, unsigned int F, typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> constexpr inline fixed<B, I, F> operator*(const fixed<B, I, F>& x, T y) noexcept { @@ -270,6 +277,13 @@ namespace fpm return fixed<B, I, F>(x) /= y; } + template <typename B, typename I, unsigned int F, typename T> + constexpr inline fixed<B, I, F> operator/(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return fixed<B, I, F>(x) /= r; + } + template <typename B, typename I, unsigned int F, typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> constexpr inline fixed<B, I, F> operator/(const fixed<B, I, F>& x, T y) noexcept { @@ -292,30 +306,65 @@ namespace fpm return x.raw_value() == y.raw_value(); } + template <typename B, typename I, unsigned int F, typename T> + constexpr inline bool operator==(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return x.raw_value() == r.raw_value(); + } + template <typename B, typename I, unsigned int F> constexpr inline bool operator!=(const fixed<B, I, F>& x, const fixed<B, I, F>& y) noexcept { return x.raw_value() != y.raw_value(); } + template <typename B, typename I, unsigned int F, typename T> + constexpr inline bool operator!=(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return x.raw_value() != r.raw_value(); + } + template <typename B, typename I, unsigned int F> constexpr inline bool operator<(const fixed<B, I, F>& x, const fixed<B, I, F>& y) noexcept { return x.raw_value() < y.raw_value(); } + template <typename B, typename I, unsigned int F, typename T > + constexpr inline bool operator<(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return x.raw_value() < r.raw_value(); + } + template <typename B, typename I, unsigned int F> constexpr inline bool operator>(const fixed<B, I, F>& x, const fixed<B, I, F>& y) noexcept { return x.raw_value() > y.raw_value(); } + template <typename B, typename I, unsigned int F, typename T> + constexpr inline bool operator>(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return x.raw_value() > r.raw_value(); + } + template <typename B, typename I, unsigned int F> constexpr inline bool operator<=(const fixed<B, I, F>& x, const fixed<B, I, F>& y) noexcept { return x.raw_value() <= y.raw_value(); } + template <typename B, typename I, unsigned int F, typename T> + constexpr inline bool operator<=(const fixed<B, I, F>& x, T y) noexcept + { + fixed<B, I, F> r = y; + return x.raw_value() <= r.raw_value(); + } + template <typename B, typename I, unsigned int F> constexpr inline bool operator>=(const fixed<B, I, F>& x, const fixed<B, I, F>& y) noexcept { @@ -324,21 +373,21 @@ namespace fpm namespace detail { - // Number of base-10 digits required to fully represent a number of bits - static constexpr int max_digits10(int bits) - { - // 8.24 fixed-point equivalent of (int)ceil(bits * std::log10(2)); - using T = long long; - return static_cast<int>((T{bits} * 5050445 + (T{1} << 24) - 1) >> 24); - } + // Number of base-10 digits required to fully represent a number of bits + static constexpr int max_digits10(int bits) + { + // 8.24 fixed-point equivalent of (int)ceil(bits * std::log10(2)); + using T = long long; + return static_cast<int>((T{bits} * 5050445 + (T{1} << 24) - 1) >> 24); + } - // Number of base-10 digits that can be fully represented by a number of bits - static constexpr int digits10(int bits) - { - // 8.24 fixed-point equivalent of (int)(bits * std::log10(2)); - using T = long long; - return static_cast<int>((T{bits} * 5050445) >> 24); - } + // Number of base-10 digits that can be fully represented by a number of bits + static constexpr int digits10(int bits) + { + // 8.24 fixed-point equivalent of (int)(bits * std::log10(2)); + using T = long long; + return static_cast<int>((T{bits} * 5050445) >> 24); + } } // namespace detail @@ -348,127 +397,127 @@ namespace fpm namespace std { -template <typename B, typename I, unsigned int F> -struct hash<fpm::fixed<B,I,F>> -{ - using argument_type = fpm::fixed<B, I, F>; - using result_type = std::size_t; - - result_type operator()(argument_type arg) const noexcept(noexcept(std::declval<std::hash<B>>()(arg.raw_value()))) { - return m_hash(arg.raw_value()); - } + template <typename B, typename I, unsigned int F> + struct hash<fpm::fixed<B,I,F>> + { + using argument_type = fpm::fixed<B, I, F>; + using result_type = std::size_t; -private: - std::hash<B> m_hash; -}; + result_type operator()(argument_type arg) const noexcept(noexcept(std::declval<std::hash<B>>()(arg.raw_value()))) { + return m_hash(arg.raw_value()); + } -template <typename B, typename I, unsigned int F> -struct numeric_limits<fpm::fixed<B,I,F>> -{ - static constexpr bool is_specialized = true; - static constexpr bool is_signed = std::numeric_limits<B>::is_signed; - static constexpr bool is_integer = false; - static constexpr bool is_exact = true; - static constexpr bool has_infinity = false; - static constexpr bool has_quiet_NaN = false; - static constexpr bool has_signaling_NaN = false; - static constexpr bool has_denorm = std::denorm_absent; - static constexpr bool has_denorm_loss = false; - static constexpr std::float_round_style round_style = std::round_to_nearest; - static constexpr bool is_iec_559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = std::numeric_limits<B>::is_modulo; - static constexpr int digits = std::numeric_limits<B>::digits; - - // Any number with `digits10` significant base-10 digits (that fits in - // the range of the type) is guaranteed to be convertible from text and - // back without change. Worst case, this is 0.000...001, so we can only - // guarantee this case. Nothing more. - static constexpr int digits10 = 1; - - // This is equal to max_digits10 for the integer and fractional part together. - static constexpr int max_digits10 = - fpm::detail::max_digits10(std::numeric_limits<B>::digits - F) + fpm::detail::max_digits10(F); - - static constexpr int radix = 2; - static constexpr int min_exponent = 1 - F; - static constexpr int min_exponent10 = -fpm::detail::digits10(F); - static constexpr int max_exponent = std::numeric_limits<B>::digits - F; - static constexpr int max_exponent10 = fpm::detail::digits10(std::numeric_limits<B>::digits - F); - static constexpr bool traps = true; - static constexpr bool tinyness_before = false; - - static constexpr fpm::fixed<B,I,F> lowest() noexcept { - return fpm::fixed<B,I,F>::from_raw_value(std::numeric_limits<B>::lowest()); + private: + std::hash<B> m_hash; }; - static constexpr fpm::fixed<B,I,F> min() noexcept { - return lowest(); - } + template <typename B, typename I, unsigned int F> + struct numeric_limits<fpm::fixed<B,I,F>> + { + static constexpr bool is_specialized = true; + static constexpr bool is_signed = std::numeric_limits<B>::is_signed; + static constexpr bool is_integer = false; + static constexpr bool is_exact = true; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm = std::denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr std::float_round_style round_style = std::round_to_nearest; + static constexpr bool is_iec_559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = std::numeric_limits<B>::is_modulo; + static constexpr int digits = std::numeric_limits<B>::digits; + + // Any number with `digits10` significant base-10 digits (that fits in + // the range of the type) is guaranteed to be convertible from text and + // back without change. Worst case, this is 0.000...001, so we can only + // guarantee this case. Nothing more. + static constexpr int digits10 = 1; + + // This is equal to max_digits10 for the integer and fractional part together. + static constexpr int max_digits10 = + fpm::detail::max_digits10(std::numeric_limits<B>::digits - F) + fpm::detail::max_digits10(F); + + static constexpr int radix = 2; + static constexpr int min_exponent = 1 - F; + static constexpr int min_exponent10 = -fpm::detail::digits10(F); + static constexpr int max_exponent = std::numeric_limits<B>::digits - F; + static constexpr int max_exponent10 = fpm::detail::digits10(std::numeric_limits<B>::digits - F); + static constexpr bool traps = true; + static constexpr bool tinyness_before = false; + + static constexpr fpm::fixed<B,I,F> lowest() noexcept { + return fpm::fixed<B,I,F>::from_raw_value(std::numeric_limits<B>::lowest()); + }; + + static constexpr fpm::fixed<B,I,F> min() noexcept { + return lowest(); + } - static constexpr fpm::fixed<B,I,F> max() noexcept { - return fpm::fixed<B,I,F>::from_raw_value(std::numeric_limits<B>::max()); - }; + static constexpr fpm::fixed<B,I,F> max() noexcept { + return fpm::fixed<B,I,F>::from_raw_value(std::numeric_limits<B>::max()); + }; - static constexpr fpm::fixed<B,I,F> epsilon() noexcept { - return fpm::fixed<B,I,F>::from_raw_value(1); - }; + static constexpr fpm::fixed<B,I,F> epsilon() noexcept { + return fpm::fixed<B,I,F>::from_raw_value(1); + }; - static constexpr fpm::fixed<B,I,F> round_error() noexcept { - return fpm::fixed<B,I,F>(1) / 2; + static constexpr fpm::fixed<B,I,F> round_error() noexcept { + return fpm::fixed<B,I,F>(1) / 2; + }; + + static constexpr fpm::fixed<B,I,F> denorm_min() noexcept { + return min(); + } }; - static constexpr fpm::fixed<B,I,F> denorm_min() noexcept { - return min(); - } -}; - -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_specialized; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_signed; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_integer; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_exact; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_infinity; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_quiet_NaN; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_signaling_NaN; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_denorm; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_denorm_loss; -template <typename B, typename I, unsigned int F> -constexpr std::float_round_style numeric_limits<fpm::fixed<B,I,F>>::round_style; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_iec_559; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_bounded; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_modulo; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::digits; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::digits10; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::max_digits10; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::radix; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::min_exponent; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::min_exponent10; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::max_exponent; -template <typename B, typename I, unsigned int F> -constexpr int numeric_limits<fpm::fixed<B,I,F>>::max_exponent10; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::traps; -template <typename B, typename I, unsigned int F> -constexpr bool numeric_limits<fpm::fixed<B,I,F>>::tinyness_before; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_specialized; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_signed; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_integer; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_exact; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_infinity; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_quiet_NaN; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_signaling_NaN; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_denorm; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::has_denorm_loss; + template <typename B, typename I, unsigned int F> + constexpr std::float_round_style numeric_limits<fpm::fixed<B,I,F>>::round_style; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_iec_559; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_bounded; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::is_modulo; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::digits; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::digits10; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::max_digits10; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::radix; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::min_exponent; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::min_exponent10; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::max_exponent; + template <typename B, typename I, unsigned int F> + constexpr int numeric_limits<fpm::fixed<B,I,F>>::max_exponent10; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::traps; + template <typename B, typename I, unsigned int F> + constexpr bool numeric_limits<fpm::fixed<B,I,F>>::tinyness_before; } diff --git a/Client/ThirdParty/fpm/include/fpm/math.hpp b/Client/ThirdParty/fpm/include/fpm/math.hpp index cf45297..3943940 100644 --- a/Client/ThirdParty/fpm/include/fpm/math.hpp +++ b/Client/ThirdParty/fpm/include/fpm/math.hpp @@ -538,7 +538,7 @@ fixed<B, I, F> sin(fixed<B, I, F> x) noexcept } const Fixed x2 = x*x; - return sign * x * (Fixed::pi() - x2*(Fixed::two_pi() - 5 - x2*(Fixed::pi() - 3)))/2; + return sign * x * (Fixed::pi() - x2*(Fixed::two_pi() - 5 - x2*(Fixed::pi() - 3)))/2.f; } template <typename B, typename I, unsigned int F> |