Puede estar obteniendo falsos positivos. Colisiones detectadas pero no realmente colisiones.
El número 15 proviene de
- 3 ejes del objeto A (caras normales)
- 3 ejes del objeto B (caras normales)
- 9 ejes de todos los pares de aristas de A y aristas de B (3x3)
- = 15 en total
Los 9 ejes están formados por productos transversales de bordes de A y bordes de B
- Ae1 x Be1 (Borde 1 de A, borde transversal 1 de B)
- Ae1 x Be2
- Ae1 x Be3
- Ae2 x Be1
- ... y así
Los primeros 6 ejes (de las normales de la cara) se utilizan para verificar si una esquina de un objeto está intersectando una cara del otro objeto. (o más correctamente para eliminar este tipo de colisiones)
El conjunto de 9 ejes formados por los productos transversales de los bordes se usa para considerar la detección de colisión de borde sobre borde, donde no hay un vértice que penetre en el otro objeto. Como la colisión 'casi' en la foto de abajo. Supongamos para el resto de esta respuesta que los dos cuadros en la imagen no están realmente colisionando, sino que están separados por una pequeña distancia.
Veamos qué sucede si solo usamos las 6 normales de cara para SAT. La primera imagen a continuación muestra un eje del cuadro azul y 2 ejes del cuadro amarillo. Si proyectamos ambos objetos en estos ejes, obtendremos una superposición en los tres. La segunda imagen a continuación muestra los dos ejes restantes del cuadro azul y el eje restante del cuadro amarillo. Una vez más, proyectar en estos ejes mostrará superposiciones en los 3.
Entonces, solo al verificar las 6 normales de la cara se mostrarán superposiciones en los 6 ejes, lo que, según el SAT, significa que los objetos están colisionando, porque no hemos podido encontrar una separación. Pero, por supuesto, estos objetos no están colisionando. ¡La razón por la que no hemos encontrado una separación es porque no hemos buscado lo suficiente!
Entonces, ¿cómo vamos a encontrar esta brecha? La siguiente imagen muestra un eje en el que la proyección de ambos objetos revelará una separación.
¿De dónde obtenemos este eje?
Si imagina deslizar un trozo de tarjeta rígida en el espacio, esa tarjeta formará parte del plano de separación. Si proyectamos a la normalidad de ese plano (flecha negra en la imagen de arriba), veremos la separación. Sabemos cuál es ese plano porque tenemos dos vectores que se encuentran en ese plano) Un vector está alineado con el borde azul y el otro vector está alineado con el borde amarillo y, como todos sabemos, la normalidad de un plano es simplemente el producto cruzado de dos vectores que yacen en el plano.
Entonces, para los OOBBs necesitamos verificar cada combinación (9 de ellas) de productos cruzados de los bordes de los dos objetos para asegurarnos de que no faltan las separaciones de borde a borde.
La respuesta de Ken señala:
Es algo confuso referirse a los bordes, ya que hay 12 bordes en comparación con 6 normales, cuando también podría usar las tres normales principales para la misma salida: los bordes están todos alineados con las normales, por lo que recomiendo usarlos en su lugar !
También tenga en cuenta que las normales que apuntan a lo largo del mismo eje, pero en una dirección diferente, se ignoran y, por lo tanto, nos quedan tres ejes únicos.
Otra cosa que me gustaría agregar es que puede optimizar este cálculo saliendo temprano si encuentra un eje de separación, antes de calcular todos los ejes que desea probar. Entonces, no, no necesita probar todos los ejes en todos los casos, pero sí debe estar listo para probarlos a todos :)
Aquí hay una lista completa de ejes para probar, dados dos OBB, A y B, donde x, y y z se refieren a los vectores base / tres normales únicas. 0 = eje x, 1 = eje y, 2 = eje z
También hay una pequeña advertencia, que debes tener en cuenta.
El producto cruzado le dará un vector cero {0,0,0} cuando dos ejes cualesquiera entre los objetos apunten en la misma dirección.
Además, dado que esta parte se omitió, aquí está mi implementación para verificar si la proyección se superpone o no. Probablemente haya una mejor manera, ¡pero esto funcionó para mí! (Usando Unity y su API C #)
fuente
ejemplo de c # de trabajo basado en la respuesta de Acegikmo (usando algunos apis de la unidad)
fuente