Estoy usando Bullet e intento hacer un algoritmo de colisión que genere puntos de contacto fuera de un terreno basado en cubos junto con la respuesta de colisión adecuada. También planeo extender esto para incluir formas que no sean cajas, sin embargo, eso no es vital en este momento. Descubrí que usar una malla triangular es demasiado RAM para mapas grandes.
He intentado el procedimiento descrito por Byte56 aquí , sin embargo, tengo varias preguntas sobre la implementación de esto con Bullet:
- ¿Cómo se genera una forma de colisión para el mundo? ¿Usas una forma personalizada? ¿Qué configuras
m_shapeType
para estar en él? - ¿O todavía utilizas una caja del tamaño del mundo?
- ¿Cómo se asegura de que se liberen los puntos de contacto?
- ¿Cómo se modifica exactamente
processCollision
?
Qué he hecho:
- He creado un terrenoShape
that extends
btBoxShape, the only difference being that
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE`, para poder registrar un nuevo algoritmo de colisión con el despachador de objetos con solo esta forma. btRigidBody
Extendí la clase de una manera similar a Byte56 en su pregunta (vea el enlace en el segundo párrafo), sin embargo,checkCollisionWith(CollisionObject * co)
devuelve verdadero si algún vóxel en el AABB deco
no es aire.He extendido la
btCollisionAlgorithm
clase, de manera similar abtCompoundCollisionAlgorithm
,processCollision
haciendo lo siguiente:- Verifique los objetos en colisión pasados como argumentos y determine cuál es el terreno y cuál es la entidad.
- Borre los múltiples algoritmos secundarios.
- Llamada
resultOut->setPersistantManifold(resultOut)
- Genere nuevas formas de caja y transformaciones en el AABB ocupado por la entidad en colisión, y luego llame
m_dispatcher->findAlgorithm
. Almacene el algoritmo de forma, transformación y encontrado en una estructura de Algoritmo Infantil para cada vóxel dentro de la AABB. - Iterar sobre todos los algoritmos secundarios, llamando
proccessCollision
. - Iterar sobre todos los algoritmos secundarios, eliminando cualquiera ahora fuera del AABB de la entidad en colisión. (llamando
~btCollisionAlgorithm()
entoncesm_dispatcher->freeCollisionAlgorithm()
) - Llamada
resultOut->refreshContactPoints()
.
Lo que funciona: processCollision
se llama cuando el AABB del jugador se cruza con vóxeles no aéreos.
Lo que no: la respuesta de colisión es simplemente extraña ... La entidad del jugador comienza a levitar hacia arriba. Si se topa con algo, rebota violentamente. A veces, no puede seguir moviéndose en un eje después de tropezar con algo. Lo que sospecho que está sucediendo es que los puntos de contacto no se liberan después de la respuesta de colisión, posiblemente debido a que la entidad del jugador siempre está en el AABB del objeto mundial. Tengo curiosidad por ver si estoy ladrando el árbol correcto con respecto a processCollision
?
fuente
Respuestas:
Desafortunadamente, no pude obtener resultados confiables del método descrito en la respuesta a la que hace referencia . Al igual que usted, obtendría eventos flotantes extraños, o situaciones en las que eliminar un vóxel provocaría que los objetos que flotaran sobre ellos permanecieran flotando en el aire, o que una extraña pluma oscilante cayera al suelo. Abandoné esa estrategia por una nueva estrategia.
Comencé a crear mallas de colisión personalizadas para cada fragmento de terreno vóxel. Lo hago con el
BvhTriangleMeshShape
. Esto funciona bastante bien:Hay más detalles sobre la aplicación de las mallas de colisión costumbre aquí .
fuente