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
?
fonte
Respostas:
Infelizmente, não consegui obter resultados confiáveis com o método descrito na resposta que você está fazendo referência . Semelhante a você, eu recebia eventos flutuantes estranhos, ou situações em que a remoção de um voxel fazia com que objetos flutuando em cima deles permanecessem flutuando no ar, ou uma estranha pena oscilante caia no chão. Abandonei essa estratégia por uma nova estratégia.
Comecei a criar malhas de colisão personalizadas para cada pedaço de terreno voxel. Eu faço isso com o
BvhTriangleMeshShape
. Isso funciona muito bem:Há mais detalhes sobre a implementação das malhas de colisão personalizadas aqui .
fonte