Perguntando box2d se uma colisão aconteceu
-
22-09-2019 - |
Pergunta
Estou usando Box2DX (portado para C#; otimizado para XNA). Ele lida com a resolução de colisão, mas como posso saber se dois objetos estão colidindo atualmente?
Esta é a função que estou tentando escrever:
public bool IsColliding(GameObjectController collider1, GameObjectController collider2)
Onde collider1.Model.Body
é o box2d Body
, e collider1.Model.BodyDef
é o box2d BodyDef
. (O mesmo vale para collider2
, é claro.)
ATUALIZAR: Parece ouvintes de contato ou isso pode ser útil:
AABB collisionBox;
model.Body.GetFixtureList().GetAABB(out collisionBox);
Porque GetFixtureList()
devolver um acessório?
Solução
Se você conhece os tipos de forma, pode usar qualquer uma das seguintes funções para verificar diretamente a sobreposição.
public static void Collision.CollideCircles(ref Manifold manifold,
CircleShape circle1, XForm xf1, CircleShape circle2, XForm xf2);
public static void Collision.CollidePolygonAndCircle(ref Manifold manifold,
PolygonShape polygon, XForm xf1, CircleShape circle, XForm xf2);
public static void Collision.CollideEdgeAndCircle(ref Manifold manifold,
EdgeShape edge, XForm transformA, CircleShape circle, XForm transformB);
public static void Collision.CollidePolyAndEdge(ref Manifold manifold,
PolygonShape polygon, XForm transformA, EdgeShape edge, XForm transformB);
public static void Collision.CollidePolygons(ref Manifold manifold,
PolygonShape polyA, XForm xfA, PolygonShape polyB, XForm xfB);
Todos eles tiram duas formas e duas transformações. O resultado é um objeto múltiplo que contém uma coleção de pontos em que os limites da forma se cruzam. Se o número de pontos for maior que zero, você terá uma colisão.
Você pode obter as mesmas informações indiretamente, implementando a interface ContactListener por uma classe.
public class MyContactListener : ContactListener {
// Called when intersection begins.
void BeginContact(Contact contact) {
// ...
// Make some indication that the two bodies collide.
// ...
}
// Called when the intersection ends.
void EndContact(Contact contact) {
// ...
// Make some indication that the two bodies no longer collide.
// ...
}
// Called before the contact is processed by the dynamics solver.
void PreSolve(Contact contact, Manifold oldManifold) {}
// Called after the contact is processed by the dynamics solver.
void PostSolve(Contact contact, ContactImpulse impulse) {}
}
A proibição de dois corpos é encontrada em contato._fixturea.body and contact._fixtureb.body. Você precisa registrar o objeto do ouvinte no mundo.
GetFixTureList (), getBodyList (), getJointList (), etc. Retorne o primeiro elemento em uma lista vinculada. O próximo elemento da lista é encontrado chamando getNext () no elemento. Você pode iterar sobre a lista com o seguinte código. Quando getNext () retorna nulo, não há mais elementos.
// Given there is a Body named body.
for (Fixture fix = body.GetFixtureList(); fix; fix = fix.GetNext()) {
// Operate on fix.
}