Physics2D: Add support for trigger and callbacks
This commit is contained in:
@@ -37,6 +37,16 @@ namespace Nz
|
||||
return m_stepSize;
|
||||
}
|
||||
|
||||
void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks)
|
||||
{
|
||||
InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), callbacks);
|
||||
}
|
||||
|
||||
void PhysWorld2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks)
|
||||
{
|
||||
InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), callbacks);
|
||||
}
|
||||
|
||||
void PhysWorld2D::SetGravity(const Vector2f& gravity)
|
||||
{
|
||||
cpSpaceSetGravity(m_handle, cpv(gravity.x, gravity.y));
|
||||
@@ -57,4 +67,99 @@ namespace Nz
|
||||
m_timestepAccumulator -= m_stepSize;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysWorld2D::InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks)
|
||||
{
|
||||
auto it = m_callbacks.emplace(handler, std::make_unique<Callback>(callbacks)).first;
|
||||
|
||||
handler->userData = &it->second;
|
||||
|
||||
if (callbacks.startCallback)
|
||||
{
|
||||
handler->beginFunc = [](cpArbiter* arb, cpSpace* space, void *data) -> cpBool
|
||||
{
|
||||
cpBody* firstBody;
|
||||
cpBody* secondBody;
|
||||
cpArbiterGetBodies(arb, &firstBody, &secondBody);
|
||||
|
||||
PhysWorld2D* world = static_cast<PhysWorld2D*>(cpSpaceGetUserData(space));
|
||||
RigidBody2D* firstRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(firstBody));
|
||||
RigidBody2D* secondRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(secondBody));
|
||||
|
||||
const Callback* customCallbacks = static_cast<const Callback*>(data);
|
||||
if (customCallbacks->startCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata))
|
||||
{
|
||||
cpBool retA = cpArbiterCallWildcardBeginA(arb, space);
|
||||
cpBool retB = cpArbiterCallWildcardBeginB(arb, space);
|
||||
return retA && retB;
|
||||
}
|
||||
else
|
||||
return cpFalse;
|
||||
};
|
||||
}
|
||||
|
||||
if (callbacks.endCallback)
|
||||
{
|
||||
handler->separateFunc = [](cpArbiter* arb, cpSpace* space, void *data)
|
||||
{
|
||||
cpBody* firstBody;
|
||||
cpBody* secondBody;
|
||||
cpArbiterGetBodies(arb, &firstBody, &secondBody);
|
||||
|
||||
PhysWorld2D* world = static_cast<PhysWorld2D*>(cpSpaceGetUserData(space));
|
||||
RigidBody2D* firstRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(firstBody));
|
||||
RigidBody2D* secondRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(secondBody));
|
||||
|
||||
const Callback* customCallbacks = static_cast<const Callback*>(data);
|
||||
customCallbacks->endCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata);
|
||||
|
||||
cpArbiterCallWildcardSeparateA(arb, space);
|
||||
cpArbiterCallWildcardSeparateB(arb, space);
|
||||
};
|
||||
}
|
||||
|
||||
if (callbacks.preSolveCallback)
|
||||
{
|
||||
handler->preSolveFunc = [](cpArbiter* arb, cpSpace* space, void *data) -> cpBool
|
||||
{
|
||||
cpBody* firstBody;
|
||||
cpBody* secondBody;
|
||||
cpArbiterGetBodies(arb, &firstBody, &secondBody);
|
||||
|
||||
PhysWorld2D* world = static_cast<PhysWorld2D*>(cpSpaceGetUserData(space));
|
||||
RigidBody2D* firstRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(firstBody));
|
||||
RigidBody2D* secondRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(secondBody));
|
||||
|
||||
const Callback* customCallbacks = static_cast<const Callback*>(data);
|
||||
if (customCallbacks->preSolveCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata))
|
||||
{
|
||||
cpBool retA = cpArbiterCallWildcardPreSolveA(arb, space);
|
||||
cpBool retB = cpArbiterCallWildcardPreSolveB(arb, space);
|
||||
return retA && retB;
|
||||
}
|
||||
else
|
||||
return cpFalse;
|
||||
};
|
||||
}
|
||||
|
||||
if (callbacks.postSolveCallback)
|
||||
{
|
||||
handler->postSolveFunc = [](cpArbiter* arb, cpSpace* space, void *data)
|
||||
{
|
||||
cpBody* firstBody;
|
||||
cpBody* secondBody;
|
||||
cpArbiterGetBodies(arb, &firstBody, &secondBody);
|
||||
|
||||
PhysWorld2D* world = static_cast<PhysWorld2D*>(cpSpaceGetUserData(space));
|
||||
RigidBody2D* firstRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(firstBody));
|
||||
RigidBody2D* secondRigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(secondBody));
|
||||
|
||||
const Callback* customCallbacks = static_cast<const Callback*>(data);
|
||||
customCallbacks->postSolveCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata);
|
||||
|
||||
cpArbiterCallWildcardPostSolveA(arb, space);
|
||||
cpArbiterCallWildcardPostSolveB(arb, space);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user