Update PhysicsSystem2D (#179)

* Update

* Add: [Get/Set]AngularDaming for standardization

* Fix: Name error

* Add: [Get/Set][AngularDamping/MomentOfInertia] in PhysicsComponent2D

* Forgot in last commit

* Add: param coordSys in [PhysicsComponent2D/RigidBody2D]::SetMassCenter

* Add: Some forgotten inline

* Fix little error

* Fix: Indentation before case

* Move and Change GetCenterOfGravity

* Rename m_world into m_physWorld

* Rename GetWorld int GetPhysWorld

* Update: PhysicsSystem2D became an interface of PhysWorld2D

* Update Collison/PhysicsComponent because GetWorld was renamed

* Update tests

* Update: Make the interface usable with Entity instead of PhysicsComponent

* Update: Make GetPhysWorld private

* Update PhysicsSystem2D.hpp

* Update: indent

* Remove: useless blank line

* update order(?)

* Update PhysicsSystem2D.hpp
This commit is contained in:
Faymoon
2018-08-07 19:08:01 +02:00
committed by Jérôme Leclercq
parent 602992609f
commit 0a5e9e040d
6 changed files with 359 additions and 18 deletions

View File

@@ -16,24 +16,112 @@ namespace Ndk
{
class NDK_API PhysicsSystem2D : public System<PhysicsSystem2D>
{
friend class CollisionComponent2D;
friend class PhysicsComponent2D;
using ContactEndCallback = std::function<void(PhysicsSystem2D& world, Nz::Arbiter2D& arbiter, const EntityHandle& bodyA, const EntityHandle& bodyB, void* userdata)>;
using ContactPreSolveCallback = std::function<bool(PhysicsSystem2D& world, Nz::Arbiter2D& arbiter, const EntityHandle& bodyA, const EntityHandle& bodyB, void* userdata)>;
using ContactPostSolveCallback = std::function<void(PhysicsSystem2D& world, Nz::Arbiter2D& arbiter, const EntityHandle& bodyA, const EntityHandle& bodyB, void* userdata)>;
using ContactStartCallback = std::function<bool(PhysicsSystem2D& world, Nz::Arbiter2D& arbiter, const EntityHandle& bodyA, const EntityHandle& bodyB, void* userdata)>;
using DebugDrawCircleCallback = std::function<void(const Nz::Vector2f& origin, float rotation, float radius, Nz::Color outlineColor, Nz::Color fillColor, void* userdata)>;
using DebugDrawDotCallback = std::function<void(const Nz::Vector2f& origin, float radius, Nz::Color color, void* userdata)>;
using DebugDrawPolygonCallback = std::function<void(const Nz::Vector2f* vertices, std::size_t vertexCount, float radius, Nz::Color outlineColor, Nz::Color fillColor, void* userdata)>;
using DebugDrawSegmentCallback = std::function<void(const Nz::Vector2f& first, const Nz::Vector2f& second, Nz::Color color, void* userdata)>;
using DebugDrawTickSegmentCallback = std::function<void(const Nz::Vector2f& first, const Nz::Vector2f& second, float thickness, Nz::Color outlineColor, Nz::Color fillColor, void* userdata)>;
using DebugDrawGetColorCallback = std::function<Nz::Color(const EntityHandle& body, std::size_t shapeIndex, void* userdata)>;
public:
struct Callback;
struct DebugDrawOptions;
struct NearestQueryResult;
struct RaycastHit;
PhysicsSystem2D();
PhysicsSystem2D(const PhysicsSystem2D& system);
~PhysicsSystem2D() = default;
Nz::PhysWorld2D& GetWorld();
const Nz::PhysWorld2D& GetWorld() const;
void DebugDraw(const DebugDrawOptions& options, bool drawShapes = true, bool drawConstraints = true, bool drawCollisions = true);
inline float GetDamping() const;
inline Nz::Vector2f GetGravity() const;
inline std::size_t GetIterationCount() const;
inline std::size_t GetMaxStepCount() const;
inline float GetStepSize() const;
bool NearestBodyQuery(const Nz::Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, EntityHandle* nearestBody = nullptr);
bool NearestBodyQuery(const Nz::Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result);
bool RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<RaycastHit>* hitInfos);
bool RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo = nullptr);
void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<EntityHandle>* bodies);
void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks);
inline void SetDamping(float dampingValue);
inline void SetGravity(const Nz::Vector2f& gravity);
inline void SetIterationCount(std::size_t iterationCount);
inline void SetMaxStepCount(std::size_t maxStepCount);
inline void SetStepSize(float stepSize);
inline void UseSpatialHash(float cellSize, std::size_t entityCount);
struct Callback
{
ContactEndCallback endCallback = nullptr;
ContactPreSolveCallback preSolveCallback = nullptr;
ContactPostSolveCallback postSolveCallback = nullptr;
ContactStartCallback startCallback = nullptr;
void* userdata;
};
struct DebugDrawOptions
{
Nz::Color constraintColor;
Nz::Color collisionPointColor;
Nz::Color shapeOutlineColor;
DebugDrawCircleCallback circleCallback;
DebugDrawGetColorCallback colorCallback;
DebugDrawDotCallback dotCallback;
DebugDrawPolygonCallback polygonCallback;
DebugDrawSegmentCallback segmentCallback;
DebugDrawTickSegmentCallback thickSegmentCallback;
void* userdata;
};
struct NearestQueryResult
{
EntityHandle nearestBody;
Nz::Vector2f closestPoint;
Nz::Vector2f fraction;
float distance;
};
struct RaycastHit
{
EntityHandle body;
Nz::Vector2f hitPos;
Nz::Vector2f hitNormal;
float fraction;
};
static SystemIndex systemIndex;
private:
void CreatePhysWorld() const;
const EntityHandle& GetEntityFromBody(const Nz::RigidBody2D& body) const;
Nz::PhysWorld2D& GetPhysWorld();
const Nz::PhysWorld2D& GetPhysWorld() const;
void OnEntityValidation(Entity* entity, bool justAdded) override;
void OnUpdate(float elapsedTime) override;
EntityList m_dynamicObjects;
EntityList m_staticObjects;
mutable std::unique_ptr<Nz::PhysWorld2D> m_world; ///TODO: std::optional (Should I make a Nz::Optional class?)
mutable std::unique_ptr<Nz::PhysWorld2D> m_physWorld; ///TODO: std::optional (Should I make a Nz::Optional class?)
};
}

View File

@@ -4,17 +4,94 @@
namespace Ndk
{
inline float PhysicsSystem2D::GetDamping() const
{
NazaraAssert(m_physWorld, "Invalid physics world");
return m_physWorld->GetDamping();
}
inline Nz::Vector2f PhysicsSystem2D::GetGravity() const
{
NazaraAssert(m_physWorld, "Invalid physics world");
return m_physWorld->GetGravity();
}
inline std::size_t PhysicsSystem2D::GetIterationCount() const
{
NazaraAssert(m_physWorld, "Invalid physics world");
return m_physWorld->GetIterationCount();
}
inline std::size_t PhysicsSystem2D::GetMaxStepCount() const
{
NazaraAssert(m_physWorld, "Invalid physics world");
return m_physWorld->GetMaxStepCount();
}
inline float PhysicsSystem2D::GetStepSize() const
{
NazaraAssert(m_physWorld, "Invalid physics world");
return m_physWorld->GetStepSize();
}
inline void PhysicsSystem2D::SetDamping(float dampingValue)
{
NazaraAssert(m_physWorld, "Invalid physics world");
m_physWorld->SetDamping(dampingValue);
}
inline void PhysicsSystem2D::SetGravity(const Nz::Vector2f& gravity)
{
NazaraAssert(m_physWorld, "Invalid physics world");
m_physWorld->SetGravity(gravity);
}
inline void PhysicsSystem2D::SetIterationCount(std::size_t iterationCount)
{
NazaraAssert(m_physWorld, "Invalid physics world");
m_physWorld->SetIterationCount(iterationCount);
}
inline void PhysicsSystem2D::SetMaxStepCount(std::size_t maxStepCount)
{
NazaraAssert(m_physWorld, "Invalid physics world");
m_physWorld->SetMaxStepCount(maxStepCount);
}
inline void PhysicsSystem2D::SetStepSize(float stepSize)
{
NazaraAssert(m_physWorld, "Invalid physics world");
m_physWorld->SetStepSize(stepSize);
}
inline void PhysicsSystem2D::UseSpatialHash(float cellSize, std::size_t entityCount)
{
NazaraAssert(m_physWorld, "Invalid physics world");
m_physWorld->UseSpatialHash(cellSize, entityCount);
}
/*!
* \brief Gets the physical world
* \return A reference to the physical world
*/
inline Nz::PhysWorld2D& PhysicsSystem2D::GetWorld()
inline Nz::PhysWorld2D& PhysicsSystem2D::GetPhysWorld()
{
if (!m_world)
if (!m_physWorld)
CreatePhysWorld();
return *m_world;
return *m_physWorld;
}
/*!
@@ -22,11 +99,11 @@ namespace Ndk
* \return A constant reference to the physical world
*/
inline const Nz::PhysWorld2D& PhysicsSystem2D::GetWorld() const
inline const Nz::PhysWorld2D& PhysicsSystem2D::GetPhysWorld() const
{
if (!m_world)
if (!m_physWorld)
CreatePhysWorld();
return *m_world;
return *m_physWorld;
}
}