ChipmunkPhysics2D/PhysicsSystem: Add query functions wrappers

This commit is contained in:
SirLynix 2023-08-10 12:05:31 +02:00
parent ab95bec41b
commit 4642ea778c
6 changed files with 234 additions and 20 deletions

View File

@ -46,7 +46,7 @@ namespace Nz
using DebugDrawGetColorCallback = std::function<Color(ChipmunkRigidBody2D& body, std::size_t shapeIndex, void* userdata)>; using DebugDrawGetColorCallback = std::function<Color(ChipmunkRigidBody2D& body, std::size_t shapeIndex, void* userdata)>;
public: public:
struct Callback; struct ContactCallbacks;
struct DebugDrawOptions; struct DebugDrawOptions;
struct NearestQueryResult; struct NearestQueryResult;
struct RaycastHit; struct RaycastHit;
@ -75,8 +75,8 @@ namespace Nz
void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(ChipmunkRigidBody2D*)>& callback); void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(ChipmunkRigidBody2D*)>& callback);
void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<ChipmunkRigidBody2D*>* bodies); void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<ChipmunkRigidBody2D*>* bodies);
void RegisterCallbacks(unsigned int collisionId, Callback callbacks); void RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks); void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks);
void SetDamping(float dampingValue); void SetDamping(float dampingValue);
void SetGravity(const Vector2f& gravity); void SetGravity(const Vector2f& gravity);
@ -90,13 +90,13 @@ namespace Nz
void UseSpatialHash(float cellSize, std::size_t entityCount); void UseSpatialHash(float cellSize, std::size_t entityCount);
ChipmunkPhysWorld2D& operator=(const ChipmunkPhysWorld2D&) = delete; ChipmunkPhysWorld2D& operator=(const ChipmunkPhysWorld2D&) = delete;
ChipmunkPhysWorld2D& operator=(ChipmunkPhysWorld2D&&) = delete; ///TODO ChipmunkPhysWorld2D& operator=(ChipmunkPhysWorld2D&&) = delete;
struct Callback struct ContactCallbacks
{ {
ContactEndCallback endCallback = nullptr; ContactEndCallback endCallback = nullptr;
ContactPreSolveCallback preSolveCallback = nullptr;
ContactPostSolveCallback postSolveCallback = nullptr; ContactPostSolveCallback postSolveCallback = nullptr;
ContactPreSolveCallback preSolveCallback = nullptr;
ContactStartCallback startCallback = nullptr; ContactStartCallback startCallback = nullptr;
void* userdata = nullptr; void* userdata = nullptr;
}; };
@ -142,13 +142,13 @@ namespace Nz
static constexpr std::size_t FreeBodyIdGrowRate = 256; static constexpr std::size_t FreeBodyIdGrowRate = 256;
void DeferBodyAction(ChipmunkRigidBody2D& rigidBody, PostStep&& func); void DeferBodyAction(ChipmunkRigidBody2D& rigidBody, PostStep&& func);
void InitCallbacks(cpCollisionHandler* handler, Callback callbacks); void InitCallbacks(cpCollisionHandler* handler, ContactCallbacks callbacks);
inline UInt32 RegisterBody(ChipmunkRigidBody2D& rigidBody); inline UInt32 RegisterBody(ChipmunkRigidBody2D& rigidBody);
inline void UnregisterBody(UInt32 bodyIndex); inline void UnregisterBody(UInt32 bodyIndex);
inline void UpdateBodyPointer(ChipmunkRigidBody2D& rigidBody); inline void UpdateBodyPointer(ChipmunkRigidBody2D& rigidBody);
std::size_t m_maxStepCount; std::size_t m_maxStepCount;
std::unordered_map<cpCollisionHandler*, std::unique_ptr<Callback>> m_callbacks; std::unordered_map<cpCollisionHandler*, std::unique_ptr<ContactCallbacks>> m_callbacks;
std::unordered_map<UInt32, std::vector<PostStep>> m_rigidBodyPostSteps; std::unordered_map<UInt32, std::vector<PostStep>> m_rigidBodyPostSteps;
std::vector<ChipmunkRigidBody2D*> m_bodies; std::vector<ChipmunkRigidBody2D*> m_bodies;
cpSpace* m_handle; cpSpace* m_handle;

View File

@ -18,10 +18,19 @@ namespace Nz
{ {
class NAZARA_CHIPMUNKPHYSICS2D_API ChipmunkPhysics2DSystem class NAZARA_CHIPMUNKPHYSICS2D_API ChipmunkPhysics2DSystem
{ {
using ContactEndCallback = std::function<void(ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
using ContactPostSolveCallback = std::function<void(ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
using ContactPreSolveCallback = std::function<bool(ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
using ContactStartCallback = std::function<bool(ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
public: public:
static constexpr Int64 ExecutionOrder = 0; static constexpr Int64 ExecutionOrder = 0;
using Components = TypeList<ChipmunkRigidBody2DComponent, class NodeComponent>; using Components = TypeList<ChipmunkRigidBody2DComponent, class NodeComponent>;
struct ContactCallbacks;
struct NearestQueryResult;
struct RaycastHit;
ChipmunkPhysics2DSystem(entt::registry& registry); ChipmunkPhysics2DSystem(entt::registry& registry);
ChipmunkPhysics2DSystem(const ChipmunkPhysics2DSystem&) = delete; ChipmunkPhysics2DSystem(const ChipmunkPhysics2DSystem&) = delete;
ChipmunkPhysics2DSystem(ChipmunkPhysics2DSystem&&) = delete; ChipmunkPhysics2DSystem(ChipmunkPhysics2DSystem&&) = delete;
@ -29,18 +38,55 @@ namespace Nz
inline ChipmunkPhysWorld2D& GetPhysWorld(); inline ChipmunkPhysWorld2D& GetPhysWorld();
inline const ChipmunkPhysWorld2D& GetPhysWorld() const; inline const ChipmunkPhysWorld2D& GetPhysWorld() const;
inline entt::handle GetRigidBodyEntity(UInt32 bodyIndex) const;
inline bool NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, entt::handle* nearestEntity = nullptr);
inline bool NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, NearestQueryResult* result);
inline void RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(const RaycastHit&)>& callback);
inline bool RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<RaycastHit>* hitInfos);
inline bool RaycastQueryFirst(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, RaycastHit* hitInfo = nullptr);
inline void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(entt::handle)>& callback);
inline void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<entt::handle>* bodies);
inline void RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks);
inline void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks);
void Update(Time elapsedTime); void Update(Time elapsedTime);
ChipmunkPhysics2DSystem& operator=(const ChipmunkPhysics2DSystem&) = delete; ChipmunkPhysics2DSystem& operator=(const ChipmunkPhysics2DSystem&) = delete;
ChipmunkPhysics2DSystem& operator=(ChipmunkPhysics2DSystem&&) = delete; ChipmunkPhysics2DSystem& operator=(ChipmunkPhysics2DSystem&&) = delete;
struct ContactCallbacks
{
ContactEndCallback endCallback = nullptr;
ContactPostSolveCallback postSolveCallback = nullptr;
ContactPreSolveCallback preSolveCallback = nullptr;
ContactStartCallback startCallback = nullptr;
void* userdata = nullptr;
};
struct NearestQueryResult : ChipmunkPhysWorld2D::NearestQueryResult
{
entt::handle nearestEntity;
};
struct RaycastHit : ChipmunkPhysWorld2D::RaycastHit
{
entt::handle nearestEntity;
};
private: private:
void OnBodyConstruct(entt::registry& registry, entt::entity entity); void OnBodyConstruct(entt::registry& registry, entt::entity entity);
void OnBodyDestruct(entt::registry& registry, entt::entity entity);
ChipmunkPhysWorld2D::ContactCallbacks SetupContactCallbacks(ContactCallbacks callbacks);
std::vector<entt::entity> m_bodyIndicesToEntity;
entt::registry& m_registry; entt::registry& m_registry;
entt::observer m_physicsConstructObserver; entt::observer m_physicsConstructObserver;
entt::scoped_connection m_bodyConstructConnection; entt::scoped_connection m_bodyConstructConnection;
entt::scoped_connection m_bodyDestructConnection;
ChipmunkPhysWorld2D m_physWorld; ChipmunkPhysWorld2D m_physWorld;
}; };
} }

View File

@ -15,6 +15,117 @@ namespace Nz
{ {
return m_physWorld; return m_physWorld;
} }
inline entt::handle ChipmunkPhysics2DSystem::GetRigidBodyEntity(UInt32 bodyIndex) const
{
return entt::handle(m_registry, m_bodyIndicesToEntity[bodyIndex]);
}
inline bool ChipmunkPhysics2DSystem::NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, entt::handle* nearestEntity)
{
ChipmunkRigidBody2D* nearestBody;
if (!m_physWorld.NearestBodyQuery(from, maxDistance, collisionGroup, categoryMask, collisionMask, &nearestBody))
return false;
if (nearestEntity)
{
if (nearestBody)
*nearestEntity = GetRigidBodyEntity(nearestBody->GetBodyIndex());
else
*nearestEntity = {};
}
return true;
}
inline bool ChipmunkPhysics2DSystem::NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, NearestQueryResult* result)
{
if (!m_physWorld.NearestBodyQuery(from, maxDistance, collisionGroup, categoryMask, collisionMask, result))
return false;
if (result)
{
if (result->nearestBody)
result->nearestEntity = GetRigidBodyEntity(result->nearestBody->GetBodyIndex());
else
result->nearestEntity = {};
}
return true;
}
inline void ChipmunkPhysics2DSystem::RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(const RaycastHit&)>& callback)
{
return m_physWorld.RaycastQuery(from, to, radius, collisionGroup, categoryMask, collisionMask, [&](const ChipmunkPhysWorld2D::RaycastHit& hitInfo)
{
RaycastHit extendedHitInfo;
static_cast<ChipmunkPhysWorld2D::RaycastHit&>(extendedHitInfo) = hitInfo;
if (extendedHitInfo.nearestBody)
extendedHitInfo.nearestEntity = GetRigidBodyEntity(extendedHitInfo.nearestBody->GetBodyIndex());
callback(extendedHitInfo);
});
}
inline bool ChipmunkPhysics2DSystem::RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<RaycastHit>* hitInfos)
{
NazaraAssert(hitInfos, "invalid output pointer");
std::size_t originalSize = hitInfos->size();
RaycastQuery(from, to, radius, collisionGroup, categoryMask, collisionMask, [&](const RaycastHit& hitInfo)
{
hitInfos->emplace_back(hitInfo);
});
return hitInfos->size() != originalSize;
}
inline bool ChipmunkPhysics2DSystem::RaycastQueryFirst(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, RaycastHit* hitInfo)
{
if (!m_physWorld.RaycastQueryFirst(from, to, radius, collisionGroup, categoryMask, collisionMask, hitInfo))
return false;
if (hitInfo)
{
if (hitInfo->nearestBody)
hitInfo->nearestEntity = GetRigidBodyEntity(hitInfo->nearestBody->GetBodyIndex());
else
hitInfo->nearestEntity = {};
}
return true;
}
inline void ChipmunkPhysics2DSystem::RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(entt::handle)>& callback)
{
return m_physWorld.RegionQuery(boundingBox, collisionGroup, categoryMask, collisionMask, [&](ChipmunkRigidBody2D* body)
{
callback(GetRigidBodyEntity(body->GetBodyIndex()));
});
}
inline void ChipmunkPhysics2DSystem::RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<entt::handle>* bodies)
{
NazaraAssert(bodies, "invalid output pointer");
return m_physWorld.RegionQuery(boundingBox, collisionGroup, categoryMask, collisionMask, [&](ChipmunkRigidBody2D* body)
{
bodies->emplace_back(GetRigidBodyEntity(body->GetBodyIndex()));
});
}
inline void ChipmunkPhysics2DSystem::RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks)
{
return m_physWorld.RegisterCallbacks(collisionId, SetupContactCallbacks(std::move(callbacks)));
}
inline void ChipmunkPhysics2DSystem::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks)
{
return m_physWorld.RegisterCallbacks(collisionIdA, collisionIdB, SetupContactCallbacks(std::move(callbacks)));
}
} }
#include <Nazara/ChipmunkPhysics2D/DebugOff.hpp> #include <Nazara/ChipmunkPhysics2D/DebugOff.hpp>

View File

@ -309,12 +309,12 @@ namespace Nz
cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y, boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height), filter, callback, bodies); cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y, boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height), filter, callback, bodies);
} }
void ChipmunkPhysWorld2D::RegisterCallbacks(unsigned int collisionId, Callback callbacks) void ChipmunkPhysWorld2D::RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks)
{ {
InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), std::move(callbacks)); InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), std::move(callbacks));
} }
void ChipmunkPhysWorld2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks) void ChipmunkPhysWorld2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks)
{ {
InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), std::move(callbacks)); InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), std::move(callbacks));
} }
@ -390,15 +390,15 @@ namespace Nz
cpSpaceUseSpatialHash(m_handle, cpFloat(cellSize), int(entityCount)); cpSpaceUseSpatialHash(m_handle, cpFloat(cellSize), int(entityCount));
} }
void ChipmunkPhysWorld2D::InitCallbacks(cpCollisionHandler* handler, Callback callbacks) void ChipmunkPhysWorld2D::InitCallbacks(cpCollisionHandler* handler, ContactCallbacks callbacks)
{ {
auto it = m_callbacks.find(handler); auto it = m_callbacks.find(handler);
if (it == m_callbacks.end()) if (it == m_callbacks.end())
it = m_callbacks.emplace(handler, std::make_unique<Callback>(std::move(callbacks))).first; it = m_callbacks.emplace(handler, std::make_unique<ContactCallbacks>(std::move(callbacks))).first;
else else
it->second = std::make_unique<Callback>(std::move(callbacks)); it->second = std::make_unique<ContactCallbacks>(std::move(callbacks));
Callback* callbackFunctions = it->second.get(); ContactCallbacks* callbackFunctions = it->second.get();
handler->userData = callbackFunctions; handler->userData = callbackFunctions;
if (callbackFunctions->startCallback) if (callbackFunctions->startCallback)
@ -415,7 +415,7 @@ namespace Nz
ChipmunkArbiter2D arbiter(arb); ChipmunkArbiter2D arbiter(arb);
const Callback* customCallbacks = static_cast<const Callback*>(data); const ContactCallbacks* customCallbacks = static_cast<const ContactCallbacks*>(data);
if (customCallbacks->startCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata)) if (customCallbacks->startCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata))
return cpTrue; return cpTrue;
else else
@ -444,7 +444,7 @@ namespace Nz
ChipmunkArbiter2D arbiter(arb); ChipmunkArbiter2D arbiter(arb);
const Callback* customCallbacks = static_cast<const Callback*>(data); const ContactCallbacks* customCallbacks = static_cast<const ContactCallbacks*>(data);
customCallbacks->endCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata); customCallbacks->endCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata);
}; };
} }
@ -469,7 +469,7 @@ namespace Nz
ChipmunkArbiter2D arbiter(arb); ChipmunkArbiter2D arbiter(arb);
const Callback* customCallbacks = static_cast<const Callback*>(data); const ContactCallbacks* customCallbacks = static_cast<const ContactCallbacks*>(data);
if (customCallbacks->preSolveCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata)) if (customCallbacks->preSolveCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata))
return cpTrue; return cpTrue;
else else
@ -498,7 +498,7 @@ namespace Nz
ChipmunkArbiter2D arbiter(arb); ChipmunkArbiter2D arbiter(arb);
const Callback* customCallbacks = static_cast<const Callback*>(data); const ContactCallbacks* customCallbacks = static_cast<const ContactCallbacks*>(data);
customCallbacks->postSolveCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata); customCallbacks->postSolveCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata);
}; };
} }

View File

@ -25,6 +25,7 @@ namespace Nz
m_physicsConstructObserver(m_registry, entt::collector.group<ChipmunkRigidBody2DComponent, NodeComponent>()) m_physicsConstructObserver(m_registry, entt::collector.group<ChipmunkRigidBody2DComponent, NodeComponent>())
{ {
m_bodyConstructConnection = registry.on_construct<ChipmunkRigidBody2DComponent>().connect<&ChipmunkPhysics2DSystem::OnBodyConstruct>(this); m_bodyConstructConnection = registry.on_construct<ChipmunkRigidBody2DComponent>().connect<&ChipmunkPhysics2DSystem::OnBodyConstruct>(this);
m_bodyDestructConnection = registry.on_destroy<ChipmunkRigidBody2DComponent>().connect<&ChipmunkPhysics2DSystem::OnBodyDestruct>(this);
} }
ChipmunkPhysics2DSystem::~ChipmunkPhysics2DSystem() ChipmunkPhysics2DSystem::~ChipmunkPhysics2DSystem()
@ -61,9 +62,65 @@ namespace Nz
} }
} }
ChipmunkPhysWorld2D::ContactCallbacks ChipmunkPhysics2DSystem::SetupContactCallbacks(ContactCallbacks callbacks)
{
ChipmunkPhysWorld2D::ContactCallbacks trampolineCallbacks;
trampolineCallbacks.userdata = callbacks.userdata;
if (callbacks.endCallback)
{
trampolineCallbacks.endCallback = [this, cb = std::move(callbacks.endCallback)](ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, ChipmunkRigidBody2D& bodyA, ChipmunkRigidBody2D& bodyB, void* userdata)
{
return cb(world, arbiter, GetRigidBodyEntity(bodyA.GetBodyIndex()), GetRigidBodyEntity(bodyB.GetBodyIndex()), userdata);
};
}
if (callbacks.preSolveCallback)
{
trampolineCallbacks.preSolveCallback = [this, cb = std::move(callbacks.preSolveCallback)](ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, ChipmunkRigidBody2D& bodyA, ChipmunkRigidBody2D& bodyB, void* userdata)
{
return cb(world, arbiter, GetRigidBodyEntity(bodyA.GetBodyIndex()), GetRigidBodyEntity(bodyB.GetBodyIndex()), userdata);
};
}
if (callbacks.postSolveCallback)
{
trampolineCallbacks.postSolveCallback = [this, cb = std::move(callbacks.postSolveCallback)](ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, ChipmunkRigidBody2D& bodyA, ChipmunkRigidBody2D& bodyB, void* userdata)
{
return cb(world, arbiter, GetRigidBodyEntity(bodyA.GetBodyIndex()), GetRigidBodyEntity(bodyB.GetBodyIndex()), userdata);
};
}
if (callbacks.startCallback)
{
trampolineCallbacks.startCallback = [this, cb = std::move(callbacks.startCallback)](ChipmunkPhysWorld2D& world, ChipmunkArbiter2D& arbiter, ChipmunkRigidBody2D& bodyA, ChipmunkRigidBody2D& bodyB, void* userdata)
{
return cb(world, arbiter, GetRigidBodyEntity(bodyA.GetBodyIndex()), GetRigidBodyEntity(bodyB.GetBodyIndex()), userdata);
};
}
return trampolineCallbacks;
}
void ChipmunkPhysics2DSystem::OnBodyConstruct(entt::registry& registry, entt::entity entity) void ChipmunkPhysics2DSystem::OnBodyConstruct(entt::registry& registry, entt::entity entity)
{ {
ChipmunkRigidBody2DComponent& rigidBody = registry.get<ChipmunkRigidBody2DComponent>(entity); ChipmunkRigidBody2DComponent& rigidBody = registry.get<ChipmunkRigidBody2DComponent>(entity);
rigidBody.Construct(m_physWorld); rigidBody.Construct(m_physWorld);
UInt32 uniqueIndex = rigidBody.GetBodyIndex();
if (uniqueIndex >= m_bodyIndicesToEntity.size())
m_bodyIndicesToEntity.resize(uniqueIndex + 1);
m_bodyIndicesToEntity[uniqueIndex] = entity;
}
void ChipmunkPhysics2DSystem::OnBodyDestruct(entt::registry& registry, entt::entity entity)
{
// Unregister owning entity
ChipmunkRigidBody2DComponent& rigidBody = registry.get<ChipmunkRigidBody2DComponent>(entity);
UInt32 uniqueIndex = rigidBody.GetBodyIndex();
assert(uniqueIndex <= m_bodyIndicesToEntity.size());
m_bodyIndicesToEntity[uniqueIndex] = entt::null;
} }
} }

View File

@ -132,7 +132,7 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
world.Step(Nz::Time::Zero()); world.Step(Nz::Time::Zero());
Nz::ChipmunkPhysWorld2D::Callback characterTriggerCallback; Nz::ChipmunkPhysWorld2D::ContactCallbacks characterTriggerCallback;
characterTriggerCallback.startCallback = [&](Nz::ChipmunkPhysWorld2D&, Nz::ChipmunkArbiter2D&, Nz::ChipmunkRigidBody2D&, Nz::ChipmunkRigidBody2D&, void*) -> bool { characterTriggerCallback.startCallback = [&](Nz::ChipmunkPhysWorld2D&, Nz::ChipmunkArbiter2D&, Nz::ChipmunkRigidBody2D&, Nz::ChipmunkRigidBody2D&, void*) -> bool {
statusTriggerCollision = statusTriggerCollision | 1 << 0; statusTriggerCollision = statusTriggerCollision | 1 << 0;
return true; return true;
@ -150,7 +150,7 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
world.RegisterCallbacks(CHARACTER_COLLISION_ID, TRIGGER_COLLISION_ID, characterTriggerCallback); world.RegisterCallbacks(CHARACTER_COLLISION_ID, TRIGGER_COLLISION_ID, characterTriggerCallback);
int statusWallCollision = 0; int statusWallCollision = 0;
Nz::ChipmunkPhysWorld2D::Callback characterWallCallback; Nz::ChipmunkPhysWorld2D::ContactCallbacks characterWallCallback;
characterWallCallback.startCallback = [&](Nz::ChipmunkPhysWorld2D&, Nz::ChipmunkArbiter2D&, Nz::ChipmunkRigidBody2D&, Nz::ChipmunkRigidBody2D&, void*) -> bool { characterWallCallback.startCallback = [&](Nz::ChipmunkPhysWorld2D&, Nz::ChipmunkArbiter2D&, Nz::ChipmunkRigidBody2D&, Nz::ChipmunkRigidBody2D&, void*) -> bool {
statusWallCollision = statusWallCollision | 1 << 0; statusWallCollision = statusWallCollision | 1 << 0;
return true; return true;