He integrado con éxito la biblioteca Bullet Physics en mi sistema de entidad / componente. Las entidades pueden chocar entre sí. Ahora necesito permitirles colisionar con el terreno, que es finito y en forma de cubo (piense en InfiniMiner o en el clon Minecraft ). Apenas comencé a usar la biblioteca Bullet Physics ayer, así que quizás me estoy perdiendo algo obvio.
Hasta ahora he extendido la RigidBody
clase para anular la checkCollisionWith(CollisionObject co)
función. Por el momento, es solo una simple verificación del origen, sin usar la otra forma. Voy a repetir eso más tarde. Por ahora se ve así:
@Override
public boolean checkCollideWith(CollisionObject co) {
Transform t = new Transform();
co.getWorldTransform(t);
if(COLONY.SolidAtPoint(t.origin.x, t.origin.y,t.origin.z)){
return true;
}
return false;
}
Esto funciona muy bien, en cuanto a detectar cuándo ocurren las colisiones. Sin embargo, esto no maneja la respuesta de colisión. Parece que la respuesta de colisión predeterminada es mover los objetos en colisión fuera de las otras formas, posiblemente sus AABB.
Por el momento, la forma del terreno es solo una caja del tamaño del mundo. Esto significa que las entidades que colisionan con el terreno simplemente se disparan fuera de esa caja de tamaño mundial. Entonces, está claro que necesito modificar la respuesta de colisión o necesito crear una forma que se adapte directamente a la forma del terreno. Entonces, ¿qué opción es mejor y cómo hago para implementarla? ¿Quizás hay una opción en la que no estoy pensando?
Cabe señalar que el terreno es dinámico y frecuentemente modificado por el jugador.
fuente
Estaba teniendo algunos problemas con la estrategia implementada en mi otra respuesta. Los puntos de contacto a veces se quedaban, era un poco raro hacer formas que no fueran cubos y a veces permitía que los objetos se deslizaran por el terreno.
Entonces, en lugar de modificar o anular cualquiera de las clases Bullet, existe una opción alternativa de usar un objeto de colisión Bullet incorporado que representará el terreno. El
BvhTriangleMeshShape
( doc ) es una forma integrada que está representada por una malla triangular.Esta malla se puede generar al mismo tiempo que la malla para visualizar el mundo. Esto significa que el objeto físico puede coincidir exactamente con el objeto renderizado.
Creo un
RigidBody
para cada trozo en mi terreno. Ese cuerpo tiene su forma establecida en aBvhTriangleMeshShape
. Cuando se modifica el terreno, al mismo tiempo que estoy reconstruyendo la representación visual del fragmento, también estoy reconstruyendo la forma física. Luego, cuando llega el momento de amortiguar la forma visual, también cambio las formas físicas de la siguiente manera:Esto asegura que el cuerpo se retire correctamente, limpiando los puntos de contacto. Luego se cambia su forma y se vuelve a agregar.
Para generar
BvhTriangleMeshShape
cada fragmento debe mantener unTriangleIndexVertexArray
( doc ). Esto es esencialmente dos buffers de byte. Uno con las posiciones de los vértices del triángulo y el otro con los índices para construir esos triángulos. Esta matriz de vértices debe mantenerse yaBvhTriangleMeshShape
que no hace una copia de los datos.El uso de todas las clases de física de Bullet integradas es probablemente más rápido que cualquier cosa que pueda escribir, y de hecho funciona muy rápido. No he visto ninguna desaceleración después de implementar esta nueva estrategia.
fuente
No estoy familiarizado con Bullet Physics, pero he usado ODE. Allí, después de la prueba de colisión sí o no, hay una prueba de colisión de forma-forma más detallada que genera un conjunto de puntos de contacto.
En su caso, su mundo es una colección de cajas, por lo que podría hacer esto:
Esto no está redefiniendo la respuesta de colisión ; Esta es una capa antes de eso. La respuesta de colisión se determina completamente por los puntos de contacto calculados a partir de la colisión.
Como dije, no estoy familiarizado con Bullet Physics, por lo que no sé si su arquitectura es adecuada para esto.
fuente