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

@@ -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);
}
void ChipmunkPhysWorld2D::RegisterCallbacks(unsigned int collisionId, Callback callbacks)
void ChipmunkPhysWorld2D::RegisterCallbacks(unsigned int collisionId, ContactCallbacks 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));
}
@@ -390,15 +390,15 @@ namespace Nz
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);
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
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;
if (callbackFunctions->startCallback)
@@ -415,7 +415,7 @@ namespace Nz
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))
return cpTrue;
else
@@ -444,7 +444,7 @@ namespace Nz
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);
};
}
@@ -469,7 +469,7 @@ namespace Nz
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))
return cpTrue;
else
@@ -498,7 +498,7 @@ namespace Nz
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);
};
}

View File

@@ -25,6 +25,7 @@ namespace Nz
m_physicsConstructObserver(m_registry, entt::collector.group<ChipmunkRigidBody2DComponent, NodeComponent>())
{
m_bodyConstructConnection = registry.on_construct<ChipmunkRigidBody2DComponent>().connect<&ChipmunkPhysics2DSystem::OnBodyConstruct>(this);
m_bodyDestructConnection = registry.on_destroy<ChipmunkRigidBody2DComponent>().connect<&ChipmunkPhysics2DSystem::OnBodyDestruct>(this);
}
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)
{
ChipmunkRigidBody2DComponent& rigidBody = registry.get<ChipmunkRigidBody2DComponent>(entity);
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;
}
}