Ocorreu um problema ao implementar o retorno de chamada de colisão no meu projeto. Eu gostaria de ter detecção entre dois objetos específicos. Tenho colisão normal, mas quero que um objeto pare ou mude de cor ou qualquer outra coisa quando colidir com outro. Eu escrevi o código do bullet wiki:
int numManifolds = dynamicsWorld->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++)
{
btManifoldPoint& pt = contactManifold->getContactPoint(j);
if (pt.getDistance()<0.f)
{
const btVector3& ptA = pt.getPositionWorldOnA();
const btVector3& ptB = pt.getPositionWorldOnB();
const btVector3& normalOnB = pt.m_normalWorldOnB;
bool x = (ContactProcessedCallback)(pt,fallRigidBody,earthRigidBody);
if(x)
printf("collision\n");
}
}
}
onde fallRigidBody é um corpo dinâmico - uma esfera e earthRigiBody é um corpo estático - StaticPlaneShape e sphere não tocam em earthRigidBody o tempo todo. Também tenho outros objetos que estão colidindo com a esfera e funciona bem. Mas o programa detecta colisão o tempo todo. Não importa se os objetos estão ou não colidindo.
Eu também adicionei após declarações de corpo rígido:
earthRigidBody->setCollisionFlags(earthRigidBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
fallRigidBody->setCollisionFlags(fallRigidBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
Então, alguém pode me dizer o que estou fazendo de errado? Talvez seja algo simples?
fonte
Respostas:
Eu estou familiarizado com o JBullet, mas como é a porta java do original, o conceito deve ser o mesmo.
Pareceu-me que sempre há uma colisão com seu plano estático e outros objetos. Mas você precisa fazer algo apenas na colisão de objetos específicos. O que você precisa usar é o ponteiro do usuário da forma de colisão. Aqui está um pedaço de código do meu próprio mecanismo em java. Aqui GameEntity é a classe que envolvo meus objetos e CollisionListener é outra classe minha que eu uso para implementar o que a colisão faz. Também passo posições e colisões normais ao ouvinte para obter efeitos mais sofisticados.
fonte
Exemplo mínimo executável
Duas esferas caindo de diferentes alturas em função do tempo.
Desde que eles começam em alturas diferentes, eles atingirão o chão em momentos diferentes.
Detectamos o impacto no solo e imprimimos em qual esfera o solo tocou quando.
Visualização Gnuplot do stdout:
Veja como:
1
X
passa para1
Código:
Testado no Bullet 2.83, Ubuntu 15.10.
GitHub upstream: https://github.com/cirosantilli/cpp-cheat/blob/d7b70153b8f86b5864c22fbc6f7005049a93491f/bullet/which_collision.cpp
fonte