Physics2D: Add support for trigger and callbacks
This commit is contained in:
@@ -11,6 +11,18 @@ namespace Nz
|
||||
{
|
||||
Collider2D::~Collider2D() = default;
|
||||
|
||||
std::vector<cpShape*> Collider2D::GenerateShapes(RigidBody2D* body) const
|
||||
{
|
||||
std::vector<cpShape*> shapes = CreateShapes(body);
|
||||
for (cpShape* shape : shapes)
|
||||
{
|
||||
cpShapeSetCollisionType(shape, m_collisionId);
|
||||
cpShapeSetSensor(shape, (m_trigger) ? cpTrue : cpFalse);
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
/******************************** BoxCollider2D *********************************/
|
||||
|
||||
BoxCollider2D::BoxCollider2D(const Vector2f& size, float radius) :
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Nz
|
||||
else
|
||||
m_geom = NullCollider2D::New();
|
||||
|
||||
m_shapes = m_geom->CreateShapes(this);
|
||||
m_shapes = m_geom->GenerateShapes(this);
|
||||
|
||||
cpSpace* space = m_world->GetHandle();
|
||||
for (cpShape* shape : m_shapes)
|
||||
|
||||
Reference in New Issue
Block a user