Physics2D/PhysWorld2D: Fix multiple calls to RegisterCallbacks with the same collision id

This commit is contained in:
Lynix 2019-04-15 16:25:40 +02:00
parent 8c7d886f73
commit e61faae089
4 changed files with 61 additions and 21 deletions

View File

@ -183,6 +183,7 @@ Nazara Engine:
- ⚠ Renamed TextStyleFlags enum to TextStyle, introduced Flags specialization of TextStyle as TextStyleFlags
- ⚠ Font, FontData and SimpleTextDrawer now use a proper TextStyleFlags instead of a UInt32
- Almost all Math algorithms are now constexpr
- PhysWorld2D: Fixed callbacks not properly replacing each others when registering twice with the same collisionId (pair)
Nazara Development Kit:
- Added ImageWidget (#139)

View File

@ -287,7 +287,7 @@ namespace Ndk
void PhysicsSystem2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks)
{
Nz::PhysWorld2D::Callback worldCallbacks{};
Nz::PhysWorld2D::Callback worldCallbacks;
if (callbacks.endCallback)
{

View File

@ -69,8 +69,8 @@ namespace Nz
void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector<Nz::RigidBody2D*>* bodies);
void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks);
void RegisterCallbacks(unsigned int collisionId, Callback callbacks);
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks);
void SetDamping(float dampingValue);
void SetGravity(const Vector2f& gravity);
@ -91,7 +91,7 @@ namespace Nz
ContactPreSolveCallback preSolveCallback = nullptr;
ContactPostSolveCallback postSolveCallback = nullptr;
ContactStartCallback startCallback = nullptr;
void* userdata;
void* userdata = nullptr;
};
struct DebugDrawOptions
@ -130,7 +130,7 @@ namespace Nz
NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/, float /*invStepCount*/);
private:
void InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks);
void InitCallbacks(cpCollisionHandler* handler, Callback callbacks);
using PostStep = std::function<void(Nz::RigidBody2D* body)>;

View File

@ -273,14 +273,14 @@ namespace Nz
cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y, boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height), filter, callback, bodies);
}
void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks)
void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, Callback callbacks)
{
InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), callbacks);
InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), std::move(callbacks));
}
void PhysWorld2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks)
void PhysWorld2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, Callback callbacks)
{
InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), callbacks);
InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), std::move(callbacks));
}
void PhysWorld2D::SetDamping(float dampingValue)
@ -341,15 +341,20 @@ namespace Nz
cpSpaceUseSpatialHash(m_handle, cpFloat(cellSize), int(entityCount));
}
void PhysWorld2D::InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks)
void PhysWorld2D::InitCallbacks(cpCollisionHandler* handler, Callback callbacks)
{
auto it = m_callbacks.emplace(handler, std::make_unique<Callback>(callbacks)).first;
auto it = m_callbacks.find(handler);
if (it == m_callbacks.end())
it = m_callbacks.emplace(handler, std::make_unique<Callback>(std::move(callbacks))).first;
else
it->second = std::make_unique<Callback>(std::move(callbacks));
handler->userData = it->second.get();
Callback* callbackFunctions = it->second.get();
handler->userData = callbackFunctions;
if (callbacks.startCallback)
if (callbackFunctions->startCallback)
{
handler->beginFunc = [](cpArbiter* arb, cpSpace* space, void *data) -> cpBool
handler->beginFunc = [](cpArbiter* arb, cpSpace* space, void*) -> cpBool
{
cpBody* firstBody;
cpBody* secondBody;
@ -372,10 +377,19 @@ namespace Nz
return cpFalse;
};
}
if (callbacks.endCallback)
else
{
handler->separateFunc = [](cpArbiter* arb, cpSpace* space, void *data)
handler->beginFunc = [](cpArbiter* arb, cpSpace* space, void*) -> cpBool
{
cpBool retA = cpArbiterCallWildcardBeginA(arb, space);
cpBool retB = cpArbiterCallWildcardBeginB(arb, space);
return retA && retB;
};
}
if (callbackFunctions->endCallback)
{
handler->separateFunc = [](cpArbiter* arb, cpSpace* space, void*)
{
cpBody* firstBody;
cpBody* secondBody;
@ -394,10 +408,18 @@ namespace Nz
cpArbiterCallWildcardSeparateB(arb, space);
};
}
if (callbacks.preSolveCallback)
else
{
handler->preSolveFunc = [](cpArbiter* arb, cpSpace* space, void *data) -> cpBool
handler->separateFunc = [](cpArbiter* arb, cpSpace* space, void*)
{
cpArbiterCallWildcardSeparateA(arb, space);
cpArbiterCallWildcardSeparateB(arb, space);
};
}
if (callbackFunctions->preSolveCallback)
{
handler->preSolveFunc = [](cpArbiter* arb, cpSpace* space, void* data) -> cpBool
{
cpBody* firstBody;
cpBody* secondBody;
@ -420,8 +442,17 @@ namespace Nz
return cpFalse;
};
}
else
{
handler->preSolveFunc = [](cpArbiter* arb, cpSpace* space, void* data) -> cpBool
{
cpBool retA = cpArbiterCallWildcardPreSolveA(arb, space);
cpBool retB = cpArbiterCallWildcardPreSolveB(arb, space);
return retA && retB;
};
}
if (callbacks.postSolveCallback)
if (callbackFunctions->postSolveCallback)
{
handler->postSolveFunc = [](cpArbiter* arb, cpSpace* space, void *data)
{
@ -442,6 +473,14 @@ namespace Nz
cpArbiterCallWildcardPostSolveB(arb, space);
};
}
else
{
handler->postSolveFunc = [](cpArbiter* arb, cpSpace* space, void* data)
{
cpArbiterCallWildcardPostSolveA(arb, space);
cpArbiterCallWildcardPostSolveB(arb, space);
};
}
}
void PhysWorld2D::OnRigidBodyMoved(RigidBody2D* oldPointer, RigidBody2D* newPointer)