Estou usando o Bullet e estou tentando criar um algoritmo de colisão que gera pontos de contato de um terreno baseado em cubo, juntamente com a resposta de colisão apropriada. Também pretendo estender isso para incluir formas que não sejam caixas, no entanto, isso não é vital no momento. Descobri que o uso de uma malha triangular é muito complicado para mapas grandes.
Eu tentei o procedimento descrito por Byte56 aqui , no entanto, tenho várias perguntas sobre a implementação disso com o Bullet:
- Como você gera uma forma de colisão para o mundo? Você usa uma forma personalizada? O que você define
m_shapeType
para estar nele? - Ou você ainda usa uma forma de caixa do tamanho do mundo?
- Como você garante que os pontos de contato sejam liberados?
- Como exatamente você modifica
processCollision
?
O que eu fiz:
- Eu criei um terrenoinShape
that extends
btBoxShape, the only difference being that
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE`, para que eu possa registrar um novo algoritmo de colisão com o despachante para objetos com apenas esse formato. btRigidBody
Estendi a classe de maneira semelhante ao Byte56 em sua pergunta (veja o link no segundo parágrafo), no entanto,checkCollisionWith(CollisionObject * co)
retorna true se algum voxel na AABB deco
não for aéreo.Estendi a
btCollisionAlgorithm
classe, de maneira semelhante abtCompoundCollisionAlgorithm
, comprocessCollision
o seguinte:- Verifique os objetos em colisão passados como argumentos e determine qual é o terreno e qual é a entidade.
- Limpe os coletores de qualquer algoritmo filho.
- Ligar
resultOut->setPersistantManifold(resultOut)
- Gere novas formas de caixa e transformações no AABB ocupado pela entidade que colide e, em seguida, chame
m_dispatcher->findAlgorithm
. Armazene a forma, a transformação e o algoritmo encontrado em uma estrutura de Algoritmo filho para cada voxel na AABB. - Iterar todos os algoritmos filhos, chamando
proccessCollision
. - Itere todos os algoritmos filhos, removendo qualquer agora fora do AABB da entidade que colide. (ligando
~btCollisionAlgorithm()
entãom_dispatcher->freeCollisionAlgorithm()
) - Ligue
resultOut->refreshContactPoints()
.
O que funciona: processCollision
é chamado sempre que o AABB do jogador cruza com voxels não aéreos.
O que não acontece: a resposta à colisão é simplesmente estranha ... A entidade jogador começa a levitar para cima. Se ele entra em algo, ele ricocheteia violentamente. Às vezes, é incapaz de continuar se movendo em um eixo depois de entrar em algo. O que eu suspeito está acontecendo é que os pontos de contato não estão sendo liberados após a resposta à colisão, possivelmente devido ao fato de a entidade jogador estar sempre no AABB do objeto mundial. Estou curioso para ver se estou latindo na árvore certa em relação a processCollision
?