Physics2D: Add NearestBodyQuery
This commit is contained in:
parent
f22dd81d35
commit
5ebf125474
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue