diff --git a/include/blitz/maths/Physics.h b/include/blitz/maths/Physics.h index d84c365..8b57aef 100644 --- a/include/blitz/maths/Physics.h +++ b/include/blitz/maths/Physics.h @@ -22,14 +22,8 @@ inline AABB operator+(const AABB& aabb, const Vec3f& offset) { return result; } -/** - * @brief returns whether the provided ray intersects with the bounding box - * - * @param ray - * @param aabb - * @return true - * @return false - */ +float Distance(const Ray& ray, const AABB& aabb); + bool Intersects(const Ray& ray, const AABB& aabb); } // namespace maths diff --git a/src/blitz/maths/Physics.cpp b/src/blitz/maths/Physics.cpp index ebed638..fdf9b83 100755 --- a/src/blitz/maths/Physics.cpp +++ b/src/blitz/maths/Physics.cpp @@ -1,6 +1,8 @@ #include "blitz/maths/Physics.h" #include "blitz/maths/Vector.h" +#include + namespace blitz { namespace maths { @@ -11,7 +13,7 @@ namespace maths { * or if any coordinate in `ray` is `NAN` or `inf` or if any coordinate in * `aabb` is `NAN` the result is unspecified. * */ -bool Intersects(const Ray& ray, const AABB& aabb) { +float Distance(const Ray& ray, const AABB& aabb) { // This function calculates smallest interval I = ] a, b [, for strictly positive a and b // such that for all t in I, for all l, r, o, d corresponding @@ -38,12 +40,23 @@ bool Intersects(const Ray& ray, const AABB& aabb) { l = Min(l, r); r = Max(l, r); + float tmin = ReduceMax(l); + float tmax = ReduceMin(r); + // Since Min propagates NANs and ReduceMin doesn't, and since NAN !< // the inequality becomes ignored for coordinates where a NAN is involved // (as a result of 0.0 / 0.0). If all coordinates are NAN, this means // that the box is reduced to a point and the ray has direction 0, - // in which case this returns false - return fmaxf(ReduceMax(l), 0.0f) < ReduceMin(r); + // in which case this returns -1 + if (tmin <= tmax) { + return std::fmaxf(tmin, 0.0f); + } + + return -1.0f; +} + +bool Intersects(const Ray& ray, const AABB& aabb) { + return Distance(ray, aabb) >= 0.0f; } } // namespace maths diff --git a/src/server/game/ServerGame.cpp b/src/server/game/ServerGame.cpp index 763521d..b304703 100644 --- a/src/server/game/ServerGame.cpp +++ b/src/server/game/ServerGame.cpp @@ -41,7 +41,7 @@ void ServerGame::CheckShoot(game::PlayerID shooter, Vec3f position, float yaw, f }; for (const auto& [playerId, player] : GetPlayers()) { - if (playerId != shooter && maths::Intersects(shootRay, playerStaticAABB + player.GetPosition()) > 0.0f) { + if (playerId != shooter && maths::Distance(shootRay, playerStaticAABB + player.GetPosition()) > 0.0f) { utils::LOG("[Server] " + player.GetName() + " a été touché !"); } } diff --git a/test/test_intersects.cpp b/test/test_intersects.cpp index 694a03e..5987307 100755 --- a/test/test_intersects.cpp +++ b/test/test_intersects.cpp @@ -10,21 +10,23 @@ using namespace blitz; using namespace maths; -#define let auto +#define let auto // sexy boiiii static void test_basic() { let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} }; let ray = Ray { {-3.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f} }; - blitz_test_assert(Intersects(ray, box)); + blitz_test_assert(Distance(ray, box)); } + + static void test_shifted() { let box = AABB { {-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f} }; let ray = Ray { {-3.0f, 0.0f, 100.0f}, {1.0f, 0.0f, 0.0f} }; - blitz_test_assert(!Intersects(ray, box)); + blitz_test_assert(!Distance(ray, box)); } int main(int argc, const char* args[]) {