diff --git a/PlayRho/Common/Fixed.hpp b/PlayRho/Common/Fixed.hpp index 66b853807b..0c6190beba 100644 --- a/PlayRho/Common/Fixed.hpp +++ b/PlayRho/Common/Fixed.hpp @@ -761,6 +761,13 @@ namespace playrho { return Abs(x - y) <= Fixed{0, static_cast(ulp)}; } + + /// @brief Gets an invalid value. + template + constexpr Fixed GetInvalid() noexcept + { + return Fixed::GetNaN(); + } /// @brief Output stream operator. template @@ -853,13 +860,6 @@ namespace playrho const auto result = lhs.Compare(rhs); return result == Fixed32::CmpResult::GreaterThan; } - - /// @brief Gets an invalid value. - template <> - constexpr Fixed32 GetInvalid() noexcept - { - return Fixed32::GetNaN(); - } /// @brief Gets the specialized name for the Fixed32 type. /// @details Provides an interface to a specialized function for getting C-style @@ -951,13 +951,6 @@ namespace playrho template<> struct Wider { using type = Fixed64; ///< Wider type. }; - - /// @brief Gets an invalid value. - template <> - constexpr Fixed64 GetInvalid() noexcept - { - return Fixed64::GetNaN(); - } /// @brief Gets the specialized name for the Fixed64 type. /// @details Provides an interface to a specialized function for getting C-style diff --git a/PlayRho/Common/Math.hpp b/PlayRho/Common/Math.hpp index 0d2563aa46..ec46f31bf5 100644 --- a/PlayRho/Common/Math.hpp +++ b/PlayRho/Common/Math.hpp @@ -303,7 +303,8 @@ AlmostEqual(T x, T y, int ulp = 2) /// @note Modulo via std::fmod appears slower than via std::trunc. /// @sa ModuloViaTrunc template -inline auto ModuloViaFmod(T dividend, T divisor) noexcept +inline typename std::enable_if::value, T>::type +ModuloViaFmod(T dividend, T divisor) noexcept { // Note: modulo via std::fmod appears slower than via std::trunc. return static_cast(std::fmod(dividend, divisor)); diff --git a/PlayRho/Dynamics/StepConf.hpp b/PlayRho/Dynamics/StepConf.hpp index a843fb796f..b34fbb60b9 100644 --- a/PlayRho/Dynamics/StepConf.hpp +++ b/PlayRho/Dynamics/StepConf.hpp @@ -152,11 +152,9 @@ class StepConf /// @brief Target depth. /// @details Target depth of overlap for calculating the TOI for CCD elligible bodies. - /// @note Must be greater than 0. - /// @note Must not be subnormal. - /// @note Must be less than twice the world's minimum vertex radius. + /// @note Recommend value that's less than twice the world's minimum vertex radius. /// @note Used in the TOI phase of step processing. - Positive targetDepth = DefaultLinearSlop * Real{3}; + Length targetDepth = DefaultLinearSlop * Real{3}; /// @brief Tolerance. /// @details The acceptable plus or minus tolerance from the target depth for TOI calculations. diff --git a/PlayRho/Dynamics/World.cpp b/PlayRho/Dynamics/World.cpp index a298e332ce..0967e58719 100644 --- a/PlayRho/Dynamics/World.cpp +++ b/PlayRho/Dynamics/World.cpp @@ -1387,6 +1387,9 @@ World::UpdateContactsData World::UpdateContactTOIs(const StepConf& conf) // Compute the TOI for this contact (one or both bodies are active and impenetrable). // Computes the time of impact in interval [0, 1] const auto output = CalcToi(c, toiConf); + assert((output.state == TOIOutput::State::e_touching) + || (output.state == TOIOutput::State::e_separated) + || (output.state == TOIOutput::State::e_overlapped)); // Use Min function to handle floating point imprecision which possibly otherwise // could provide a TOI that's greater than 1. diff --git a/Testbed/Tests/SolarSystem.hpp b/Testbed/Tests/SolarSystem.hpp index fb391d422a..6449b785b7 100644 --- a/Testbed/Tests/SolarSystem.hpp +++ b/Testbed/Tests/SolarSystem.hpp @@ -83,6 +83,12 @@ class SolarSystem: public Test os << " km (" << minName << "), to "; os << static_cast(Real{maxRadius / 1_km}); os << " km (" << maxName << ")."; + if (std::is_same::value) + { + os << "\n\n"; + os << "Note: recompile with playrho::Real set to use double (or bigger)"; + os << " for collisions to work better at these scales."; + } auto conf = Test::Conf{}; conf.description = os.str(); @@ -93,7 +99,7 @@ class SolarSystem: public Test conf.neededSettings |= (1u << NeedDrawLabelsField); conf.neededSettings |= (1u << NeedMaxTranslation); conf.neededSettings |= (1u << NeedDeltaTime); - conf.settings.linearSlop = 1000.0f; // minRadius / 1000_m; + conf.settings.linearSlop = 200 * 1000.0f; // 200_km; conf.settings.cameraZoom = 2.2e11f; conf.settings.drawLabels = true; conf.settings.maxTranslation = std::numeric_limits::infinity(); @@ -106,7 +112,7 @@ class SolarSystem: public Test SolarSystem(): Test(GetTestConf()) { m_world.SetGravity(LinearAcceleration2{}); - const auto DynamicBD = BodyDef{}.UseType(BodyType::Dynamic); + const auto DynamicBD = BodyDef{}.UseType(BodyType::Dynamic).UseBullet(true); for (auto& sso: SolarSystemBodies) { const auto p = sso.orbitalPeriod;