From b2185f21381f1a55698808a88b4e59cd0e393dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Tue, 12 Jun 2018 15:11:16 +0200 Subject: [PATCH] Physics2D/RigidBody2D: Add ClosestPointQuery method --- ChangeLog.md | 2 ++ .../NDK/Components/PhysicsComponent2D.hpp | 2 ++ .../NDK/Components/PhysicsComponent2D.inl | 18 +++++++++++ include/Nazara/Physics2D/RigidBody2D.hpp | 2 ++ src/Nazara/Physics2D/RigidBody2D.cpp | 32 +++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index a09c07788..5eb093e46 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -114,6 +114,7 @@ Nazara Engine: - Fixed a lot of classes not having their move constructor/assignation operator marked noexcept - ⚠️ SocketPoller::Wait now returns the number of socket marked as ready, and takes an additional optional parameter allowing to query the last error. - SocketPoller will now silently ignore "interrupt errors" +- Added RigidBody2D::ClosestPointQuery Nazara Development Kit: - Added ImageWidget (#139) @@ -164,6 +165,7 @@ Nazara Development Kit: - Fixed EntityOwner move assignment which was losing entity ownership - Add GraphicsComponent:ForEachRenderable method - Fixed GraphicsComponent reflective material count which was not initialized +- Added PhysicsComponent2D::ClosestPointQuery # 0.4: diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index 5c4081652..efd30602a 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -30,6 +30,8 @@ namespace Ndk void AddImpulse(const Nz::Vector2f& impulse, const Nz::Vector2f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global); void AddTorque(float torque); + bool ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint, float* closestDistance) const; + Nz::Rectf GetAABB() const; float GetAngularVelocity() const; Nz::Vector2f GetCenterOfGravity(Nz::CoordSys coordSys = Nz::CoordSys_Local) const; diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.inl b/SDK/include/NDK/Components/PhysicsComponent2D.inl index 03f98bf0b..b6628467d 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent2D.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequisites.hpp +#include #include namespace Ndk @@ -97,6 +98,23 @@ namespace Ndk m_object->AddTorque(torque); } + /*! + * \brief Finds the closest point on the entity relative to a position + * \return True if such a point exists (will return false if no collider exists) + * + * \param position The starting point which will be used for the query + * \param closestPoint The closest point on entity surface + * \param closestDistance The distance between the closest point and the starting point, may be negative if starting point is inside the entity + * + * \remark Produces a NazaraAssert if the physics object is invalid + */ + inline bool PhysicsComponent2D::ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint, float* closestDistance) const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->ClosestPointQuery(position, closestPoint, closestDistance); + } + /*! * \brief Gets the AABB of the physics object * \return AABB of the object diff --git a/include/Nazara/Physics2D/RigidBody2D.hpp b/include/Nazara/Physics2D/RigidBody2D.hpp index 4ca95717f..3b74a1943 100644 --- a/include/Nazara/Physics2D/RigidBody2D.hpp +++ b/include/Nazara/Physics2D/RigidBody2D.hpp @@ -36,6 +36,8 @@ namespace Nz void AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys = CoordSys_Global); void AddTorque(float torque); + bool ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint = nullptr, float* closestDistance = nullptr) const; + void EnableSimulation(bool simulation); Rectf GetAABB() const; diff --git a/src/Nazara/Physics2D/RigidBody2D.cpp b/src/Nazara/Physics2D/RigidBody2D.cpp index 6e61af384..c2cb31c4f 100644 --- a/src/Nazara/Physics2D/RigidBody2D.cpp +++ b/src/Nazara/Physics2D/RigidBody2D.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace Nz @@ -127,6 +128,37 @@ namespace Nz cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + ToRadians(torque)); } + bool RigidBody2D::ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint, float* closestDistance) const + { + cpVect pos = cpv(cpFloat(position.x), cpFloat(position.y)); + + float minDistance = std::numeric_limits::infinity(); + Nz::Vector2f closest; + for (cpShape* shape : m_shapes) + { + cpPointQueryInfo result; + cpShapePointQuery(shape, pos, &result); + + float resultDistance = float(result.distance); + if (resultDistance < minDistance) + { + closest.Set(float(result.point.x), float(result.point.y)); + minDistance = resultDistance; + } + } + + if (std::isinf(minDistance)) + return false; + + if (closestPoint) + *closestPoint = closest; + + if (minDistance) + *closestDistance = minDistance; + + return true; + } + void RigidBody2D::EnableSimulation(bool simulation) { if (m_isRegistered != simulation)