Physics2D: Add NearestBodyQuery

This commit is contained in:
Jérôme Leclercq 2017-03-01 17:40:12 +01:00
parent f22dd81d35
commit 5ebf125474
6 changed files with 101 additions and 4 deletions

View File

@ -42,13 +42,19 @@ namespace Nz
virtual float ComputeInertialMatrix(float mass) const = 0; virtual float ComputeInertialMatrix(float mass) const = 0;
inline Nz::UInt32 GetCategoryMask() const;
inline Nz::UInt32 GetCollisionGroup() const;
inline unsigned int GetCollisionId() const; inline unsigned int GetCollisionId() const;
inline Nz::UInt32 GetCollisionMask() const;
virtual ColliderType2D GetType() const = 0; virtual ColliderType2D GetType() const = 0;
inline bool IsTrigger() const; inline bool IsTrigger() const;
inline void SetCollisionId(unsigned long typeId); inline void SetCategoryMask(Nz::UInt32 categoryMask);
inline void SetCollisionGroup(Nz::UInt32 groupId);
inline void SetCollisionId(unsigned int typeId);
inline void SetCollisionMask(Nz::UInt32 mask);
inline void SetTrigger(bool trigger); inline void SetTrigger(bool trigger);
Collider2D& operator=(const Collider2D&) = delete; Collider2D& operator=(const Collider2D&) = delete;
@ -61,7 +67,10 @@ namespace Nz
virtual std::vector<cpShape*> CreateShapes(RigidBody2D* body) const = 0; virtual std::vector<cpShape*> CreateShapes(RigidBody2D* body) const = 0;
bool m_trigger; bool m_trigger;
Nz::UInt32 m_categoryMask;
Nz::UInt32 m_collisionGroup;
unsigned int m_collisionId; unsigned int m_collisionId;
Nz::UInt32 m_collisionMask;
private: private:
virtual std::vector<cpShape*> GenerateShapes(RigidBody2D* body) const; virtual std::vector<cpShape*> GenerateShapes(RigidBody2D* body) const;

View File

@ -2,32 +2,66 @@
// This file is part of the "Nazara Engine - Physics 2D module" // This file is part of the "Nazara Engine - Physics 2D module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Physics2D/Collider2D.hpp>
#include <memory> #include <memory>
#include <Nazara/Physics2D/Debug.hpp> #include <Nazara/Physics2D/Debug.hpp>
namespace Nz namespace Nz
{ {
inline Collider2D::Collider2D() : inline Collider2D::Collider2D() :
m_trigger(false),
m_categoryMask(0xFFFFFFFF),
m_collisionGroup(0),
m_collisionId(0), m_collisionId(0),
m_trigger(false) m_collisionMask(0xFFFFFFFF)
{ {
} }
inline Nz::UInt32 Collider2D::GetCategoryMask() const
{
return m_categoryMask;
}
inline Nz::UInt32 Collider2D::GetCollisionGroup() const
{
return m_collisionGroup;
}
inline unsigned int Collider2D::GetCollisionId() const inline unsigned int Collider2D::GetCollisionId() const
{ {
return m_collisionId; return m_collisionId;
} }
inline Nz::UInt32 Collider2D::GetCollisionMask() const
{
return m_collisionMask;
}
inline bool Collider2D::IsTrigger() const inline bool Collider2D::IsTrigger() const
{ {
return m_trigger; return m_trigger;
} }
inline void Collider2D::SetCollisionId(unsigned long typeId) inline void Collider2D::SetCategoryMask(Nz::UInt32 categoryMask)
{
m_categoryMask = categoryMask;
}
inline void Collider2D::SetCollisionGroup(Nz::UInt32 groupId)
{
m_collisionGroup = groupId;
}
inline void Collider2D::SetCollisionId(unsigned int typeId)
{ {
m_collisionId = typeId; m_collisionId = typeId;
} }
inline void Collider2D::SetCollisionMask(Nz::UInt32 mask)
{
m_collisionMask = mask;
}
inline void Collider2D::SetTrigger(bool trigger) inline void Collider2D::SetTrigger(bool trigger)
{ {
m_trigger = trigger; m_trigger = trigger;
@ -108,4 +142,3 @@ namespace Nz
} }
#include <Nazara/Physics2D/DebugOff.hpp> #include <Nazara/Physics2D/DebugOff.hpp>
#include "Collider2D.hpp"

View File

@ -8,6 +8,7 @@
#define NAZARA_PHYSWORLD2D_HPP #define NAZARA_PHYSWORLD2D_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Math/Vector2.hpp> #include <Nazara/Math/Vector2.hpp>
#include <Nazara/Physics2D/Config.hpp> #include <Nazara/Physics2D/Config.hpp>
#include <memory> #include <memory>
@ -29,6 +30,7 @@ namespace Nz
public: public:
struct Callback; struct Callback;
struct NearestQueryResult;
PhysWorld2D(); PhysWorld2D();
PhysWorld2D(const PhysWorld2D&) = delete; PhysWorld2D(const PhysWorld2D&) = delete;
@ -39,6 +41,8 @@ namespace Nz
cpSpace* GetHandle() const; cpSpace* GetHandle() const;
float GetStepSize() const; float GetStepSize() const;
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result);
void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks); void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks); void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks);
@ -59,6 +63,17 @@ namespace Nz
void* userdata; void* userdata;
}; };
struct NearestQueryResult
{
Nz::RigidBody2D* nearestBody;
Nz::Vector2f closestPoint;
Nz::Vector2f fraction;
float distance;
};
NazaraSignal(OnPhysWorld2DPreStep, const PhysWorld2D* /*physWorld*/);
NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/);
private: private:
void InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks); void InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks);

View File

@ -13,9 +13,12 @@ namespace Nz
std::vector<cpShape*> Collider2D::GenerateShapes(RigidBody2D* body) const std::vector<cpShape*> Collider2D::GenerateShapes(RigidBody2D* body) const
{ {
cpShapeFilter filter = cpShapeFilterNew(m_collisionGroup, m_categoryMask, m_collisionMask);
std::vector<cpShape*> shapes = CreateShapes(body); std::vector<cpShape*> shapes = CreateShapes(body);
for (cpShape* shape : shapes) for (cpShape* shape : shapes)
{ {
cpShapeSetFilter(shape, filter);
cpShapeSetCollisionType(shape, m_collisionId); cpShapeSetCollisionType(shape, m_collisionId);
cpShapeSetSensor(shape, (m_trigger) ? cpTrue : cpFalse); cpShapeSetSensor(shape, (m_trigger) ? cpTrue : cpFalse);
} }

View File

@ -37,6 +37,35 @@ namespace Nz
return m_stepSize; return m_stepSize;
} }
bool PhysWorld2D::NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result)
{
cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask);
if (result)
{
cpPointQueryInfo queryInfo;
if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, &queryInfo))
{
result->closestPoint.Set(queryInfo.point.x, queryInfo.point.y);
result->distance = queryInfo.distance;
result->fraction.Set(queryInfo.gradient.x, queryInfo.gradient.y);
result->nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(shape));
return true;
}
else
return false;
}
else
{
if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, nullptr))
return true;
else
return false;
}
}
void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks) void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks)
{ {
InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), callbacks); InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), callbacks);
@ -63,7 +92,12 @@ namespace Nz
while (m_timestepAccumulator >= m_stepSize) while (m_timestepAccumulator >= m_stepSize)
{ {
OnPhysWorld2DPreStep(this);
cpSpaceStep(m_handle, m_stepSize); cpSpaceStep(m_handle, m_stepSize);
OnPhysWorld2DPostStep(this);
m_timestepAccumulator -= m_stepSize; m_timestepAccumulator -= m_stepSize;
} }
} }

View File

@ -229,7 +229,10 @@ namespace Nz
cpSpace* space = m_world->GetHandle(); cpSpace* space = m_world->GetHandle();
for (cpShape* shape : m_shapes) for (cpShape* shape : m_shapes)
{
cpShapeSetUserData(shape, this);
cpSpaceAddShape(space, shape); cpSpaceAddShape(space, shape);
}
cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass)); cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass));
} }