Physics2D/PhysWorld: Add Raycast queries
This commit is contained in:
parent
f88174c8ca
commit
ede6dd90b8
|
|
@ -31,6 +31,7 @@ namespace Nz
|
||||||
public:
|
public:
|
||||||
struct Callback;
|
struct Callback;
|
||||||
struct NearestQueryResult;
|
struct NearestQueryResult;
|
||||||
|
struct RaycastHit;
|
||||||
|
|
||||||
PhysWorld2D();
|
PhysWorld2D();
|
||||||
PhysWorld2D(const PhysWorld2D&) = delete;
|
PhysWorld2D(const PhysWorld2D&) = delete;
|
||||||
|
|
@ -44,6 +45,9 @@ namespace Nz
|
||||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
|
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
|
||||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result);
|
bool NearestBodyQuery(const 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 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);
|
||||||
|
|
||||||
|
|
@ -72,6 +76,14 @@ namespace Nz
|
||||||
float distance;
|
float distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaycastHit
|
||||||
|
{
|
||||||
|
Nz::RigidBody2D* nearestBody;
|
||||||
|
Nz::Vector2f hitPos;
|
||||||
|
Nz::Vector2f hitNormal;
|
||||||
|
float fraction;
|
||||||
|
};
|
||||||
|
|
||||||
NazaraSignal(OnPhysWorld2DPreStep, const PhysWorld2D* /*physWorld*/);
|
NazaraSignal(OnPhysWorld2DPreStep, const PhysWorld2D* /*physWorld*/);
|
||||||
NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/);
|
NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,58 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PhysWorld2D::RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<RaycastHit>* hitInfos)
|
||||||
|
{
|
||||||
|
auto callback = [](cpShape* shape, cpVect point, cpVect normal, cpFloat alpha, void* data)
|
||||||
|
{
|
||||||
|
std::vector<RaycastHit>* results = reinterpret_cast<std::vector<RaycastHit>*>(data);
|
||||||
|
|
||||||
|
RaycastHit hitInfo;
|
||||||
|
hitInfo.fraction = alpha;
|
||||||
|
hitInfo.hitNormal.Set(normal.x, normal.y);
|
||||||
|
hitInfo.hitPos.Set(point.x, point.y);
|
||||||
|
hitInfo.nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(shape));
|
||||||
|
|
||||||
|
results->emplace_back(std::move(hitInfo));
|
||||||
|
};
|
||||||
|
|
||||||
|
cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask);
|
||||||
|
|
||||||
|
std::size_t previousSize = hitInfos->size();
|
||||||
|
cpSpaceSegmentQuery(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, callback, hitInfos);
|
||||||
|
|
||||||
|
return hitInfos->size() != previousSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysWorld2D::RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo)
|
||||||
|
{
|
||||||
|
cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask);
|
||||||
|
|
||||||
|
if (hitInfo)
|
||||||
|
{
|
||||||
|
cpSegmentQueryInfo queryInfo;
|
||||||
|
|
||||||
|
if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, &queryInfo))
|
||||||
|
{
|
||||||
|
hitInfo->fraction = queryInfo.alpha;
|
||||||
|
hitInfo->hitNormal.Set(queryInfo.normal.x, queryInfo.normal.y);
|
||||||
|
hitInfo->hitPos.Set(queryInfo.point.x, queryInfo.point.y);
|
||||||
|
hitInfo->nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(queryInfo.shape));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, 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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue