See discussions, stats, and author profiles for this publication at: https://www.researchgate.net/publication/345969391 Métodos y aproximaciones implementadas por los videojuegos para una óptima detección de colisiones Research Proposal · November 2020 DOI: 10.13140/RG.2.2.19285.86241 CITATIONS READS 0 643 3 authors: Leonardo David Vergara Márquez Camilo Andres Cespedes Jimenez Universidad del Norte (Colombia) Universidad del Norte (Colombia) 1 PUBLICATION 0 CITATIONS 2 PUBLICATIONS 0 CITATIONS SEE PROFILE SEE PROFILE Isaac Alejandro Blanco Universidad del Norte (Colombia) 1 PUBLICATION 0 CITATIONS SEE PROFILE Some of the authors of this publication are also working on these related projects: Métodos y aproximaciones implementadas por los videojuegos para una óptima detección de colisiones. View project All content following this page was uploaded by Isaac Alejandro Blanco on 17 November 2020. The user has requested enhancement of the downloaded file. Métodos y aproximaciones implementadas por los videojuegos para una óptima detección de colisiones. Presentan: Isaac Blanco Amador Camilo Cespedes Jiménez Kairo Tapias Paternina Leonardo Vergara Marquez Directora: Rocío Ramos Rodríguez UNIVERSIDAD DEL NORTE DEPARTAMENTO DE INGENIERIA DE SISTEMAS Y COMPUTACION Barranquilla, 5 de noviembre de 2020 1 Contenido Resumen ....................................................................................................................................... 3 Abstract ........................................................................................................................................ 5 CAPITULO I .....................................................................................................................7 INTRODUCCIÓN..............................................................................................................7 Enfoque de la investigación.............................................................................................7 CAPITULO II .................................................................................................................. 13 OBJETIVOS .................................................................................................................... 13 Objetivo general ........................................................................................................... 13 Objetivos específicos ..................................................................................................... 13 CAPITULO III................................................................................................................. 14 MARCO TEORICO ......................................................................................................... 14 CAPITULO IV ................................................................................................................. 63 CONCLUSIONES ............................................................................................................ 63 CAPITULO V .................................................................................................................. 65 BIBLIOGRAFIA.............................................................................................................. 65 2 Resumen La computación desde el inicio siempre ha buscado llevar la realidad física a un modelo matemático que nos permita entender y poder analizar desde múltiples perspectivas que no serían posibles desde nuestras limitaciones físicas. Uno de los grandes papeles que cultivo fue el campo de las simulaciones, donde su creación significo un gran avance a la hora de realizar investigaciones respecto a cualquier campo de estudio. Esto nos permitía estudiar las múltiples reacciones que podía tener un acontecimiento, donde nosotros en tiempo real podríamos ir variando parámetros y las situaciones sin necesidad de recrearlos. Un campo que nació gracias a esta posibilidad fue el campo de los videojuegos donde la computación ayudo a llevar la creatividad de una persona al plano computacional, sin embargo, en la creación de estos mundos digitales era necesario reglas parecidas a nuestro entorno físico. Muchos de los algoritmos usados para ciertas simulaciones tomaban un tiempo de cómputo extremadamente largo para la rapidez de procesamiento que necesitaban los videojuegos, lo que llevo a los ingenieros de sistemas de cada época a la creación de soluciones ingeniosas y eficientes para cada situación que se presentara. Haciendo uso de múltiples estructuras de datos y artificios matemáticos, con el paso de los años, se pudieron generar mayores precisiones a partir de una misma idea, la caja de colisión, gracias al perfeccionamiento de esta idea, los cálculos se reducían a la simple intercepción de estas mismas. 3 Con el paso del tiempo, de manera análoga gracias a la ley de Moore, ayudo a la creación de algoritmos muchos más precisos y eficientes y videoconsolas con una mayor cantidad de procesamiento, llevando el campo de la creación de videojuegos a una explosión creativa y técnica inimaginable, generando situaciones de colisiones lo más parecidas a la realidad. A lo largo de esta investigación se irán analizando desde las ideas más básicas de colisiones en el plano más simple, las dos dimensiones, viendo como estas escalaron y fueron avanzando hasta su perfeccionamiento, para luego realizar el salto a las tres dimensiones, donde se analizarán como se abordó el problema usando el mismo concepto y haciendo uso de algoritmos previamente inutilizables. Palabras clave: Computación, modelo matemático, simulaciones, entorno físico, eficiencia, algoritmo, estructura de datos. 4 Abstract Computing from the beginning has always sought to bring physical reality to a mathematical model that allows us to understand and analyze from multiple perspectives that would not be possible from our physical limitations. One of the great roles that I cultivate was the field of simulations, where its creation represented a great advance when conducting research in any field of study. This allowed us to study the multiple reactions that an event could have, where we in real time could vary parameters and situations without having to recreate them. A field that was born thanks to this possibility was the field of video games where computing helped to bring a person's creativity to the computational plane, however, in the creation of these digital worlds, rules similar to our physical environment were necessary. Many of the algorithms used for certain simulations took extremely long computation time for the speed of processing that video games needed, which led the systems engineers of each era to create ingenious and efficient solutions for each situation that arose. Making use of multiple data structures and mathematical artifacts, over the years, greater precision could be generated from the same idea, the collision box, thanks to the improvement of this idea, the calculations were reduced to the simple interception of these. Over time, in an analogous way thanks to Moore's law, I help to create much more precise and efficient algorithms and game consoles with a greater amount of processing, taking the field of video game creation to a creative and technical explosion unimaginable, generating collision situations as close to reality as possible. 5 Throughout this research, the most basic ideas of collisions in the simplest plane, the two dimensions, will be analyzed from the most basic ideas, seeing how they escalated and progressed until their perfection, to then make the jump to three dimensions, where they will be analyzed how the problem was approached using the same concept and making use of previously unusable algorithms. Keywords: Computing, Mathematical model, simulations, physical environment, efficient, algorithm, data structures. 6 CAPITULO I INTRODUCCIÓN Enfoque de la investigación Desde la creación del Tennis for Two (El primer videojuego de la historia) en el año 1958 por William Higinbotham y Robert Dvorak, se pudo ver que un videojuego podía llevar cosas del mundo físico a su entorno, como lo era en este caso el deporte del tenis, llevando el característico enfrentamiento entre dos tenistas al movimiento de una esfera alrededor de un plano en dos dimensiones donde tu podías elegir el ángulo y dirección de golpe inmediatamente cruzaba tu campo. Ilustración 1. Imagen del juego Tennis For Two Extraída de: https://sectagamer.com/curiosidades/el-primer-videojuego-de-la-historia-tennis-for-two/ Pero desde ese momento se pudo observar que las computadoras podían detectar dentro de ellas misma una mínima noción del mundo físico y sus reglas, en este caso las detecciones de colisiones o choques. 7 Pero para empezar a hablar de colisiones en el plano de los videojuegos, primeramente, necesitamos entender que es una colisión en el mundo físico y que las componen. Con las pequeñas nociones anteriores, a inicios del año 1972 empresas como Atari empezaron con el desarrollo de múltiples videojuegos con sistemas físicos propios en cada uno como los manejados para los juegos de Pong, Space Invaders y Asteroids, donde cada uno usaba abstracciones del plano físico, en distintas maneras, es decir, Pong lleva a otro nivel la idea Tennis for Two, Space Invaders y Asteroids usan el concepto de quebrantamiento y proyectil. Con el paso del tiempo, como evidencia de la ley de Moore, el crecimiento de la tecnología provoco que muchas empresas como Nintendo y Sega produjeran consolas de videojuegos que permitieran no solo una mayor capacidad de procesamiento, sino que videojuegos con mayor complejidad, como el nacimiento de los plataformeros Mario y Sonic, donde la sola descomposición de sus sistemas de físicas, demuestran un gran avance comparado con los anteriores mencionados, características como cantidad de momento, saltos, velocidad, proyectiles, colisiones espontaneas, fricción… y todo esa cantidad de operaciones en tiempo de ejecución casi inmediato, debido a los algoritmos ingeniosos y eficientes que usaban para esto. Todos estos juegos de plataformas que surgieron durante la época de auge lograron introducir a los demás juegos, lo que se conoce hoy en día como Hitbox o caja de colisiones, que otros juegos lograron diversificar para un mejor rendimiento en su género, lo que llevo a la creación de nuevos algoritmos y técnicas para mejorar su procesamiento. 8 Ilustración 2. Caja de colisión manejada por el videojuego Sonic The Hedgehog Extraida de https://info.sonicretro.org/Sonic_collision_bugs Por causa de lo anterior, años más tarde, con el inicio de los juegos de pelea como Street Fighter y Mortal Kombat, dieron paso a nuevas técnicas de detección más inmediata y más espontaneas haciendo uso de cambios en la idea de Hitbox, debido a lo acelerado sistema de juego presentaba. Pasado un tiempo dichas técnicas fueron logrando un perfeccionamiento, tanto las más simples como las avanzadas, esto sumada con la gran revolución tanto en ideas como algoritmos, dieron paso a técnicas más precisas y costeables a la hora de computar. Ilustración 3. Caja de colisión partida manejada por el personaje de Dhalsim de Street Fighter Extraída de: 2https://www.hobbyconsolas.com/reportajes/son-hitbox-son-cruciales-videojuegos-aprende-hobbybasics-691145 9 Por último, terminando el siglo XX, durante la época de los 90’s, muchas empresas logran hacer un salto tecnológico que revoluciona el mundo de las colisiones y los videojuegos, el paso a la tecnología de tres dimensiones, donde se destacan tres precursores: Doom del año 1993 de ID Software, Super Mario 64 del año 1996 y Super Smash Bros del año 1999 de Nintendo, donde logran llevar a la nueva generación de consolas, técnicas más avanzadas. En el caso de Doom, podemos observar la creación de la técnica de Ray-casting que lograba “simular” un espacio en tres dimensiones, lo que les permitió generar una mejor experiencia al usuario, además de la implementación del apartado de la física de la óptica para este propósito, que en la actualidad fue implementada directamente a las librerías de NVIDIA, lo que ayuda a la generación de mejores texturas y gráficos. Por el lado de Nintendo, la múltiple mezcla de técnicas físicas en Super Mario 64, donde podemos ver la implementación de una cámara, deslizamientos, fricción, plataformas inestables, cantidad de movimiento, velocidad, lanzamiento de objetos, explosiones, partículas… siendo una ejemplificación del plataformero inicial en tres dimensiones ideal. Acto seguido, el juego de Super Smash Bros no incurrió en nuevos algoritmos, con respecto al juego de pelea, sin embargo, con el auge competitivo de este, se encargo de llevar las cajas de colisiones a un nivel de exactitud muy preciso, además de la introducción de conceptos de objetos estacionarios y sus interacciones, que servirían para aproximaciones voraces para otros juegos como los FPS. 10 Ilustración 4. Caja de colisiones de un golpe de Link del juego Super Smash Bros Melee Extraída de: Virtuosos on the Screen: Playing Virtual Characters Like Instruments in Competitive Super Smash Bros. Melee Con el paso del tiempo, y el surgimiento de nuevas tecnologías llevo a la creación de nuevas técnicas, y el funcionamiento ideal de los previamente utilizados tanto en tres como dos dimensiones, debido al gran poder de computación y procesamiento, llevando a ciertos algoritmos que antes no se utilizaban debido a su alto coste relativo en ese entonces, como lo pueden ser el algoritmo de Convex Hull para las figuras en 3D. Actualmente las cajas de colisión y su detección cuentan con un nivel de precisión bastante alto, debido a lo antes mencionado, tomando ejemplos como el uso del algoritmo de OBB para la generación de esqueletos que cubran todo el volumen del personaje, un buen ejemplo de dicha técnica, son las cajas de colisiones manejadas por el Shooter táctico de Valve, Counter Strike Global Ofensive, desarrollado en el año 2012 11 Ilustración 5. Caja de colisión del Shooter Counter Strike Global Offensive Extraída de: https://counterstrike.fandom.com/wiki/Hitbox 12 CAPITULO II OBJETIVOS Objetivo general • Contrastar las diferentes técnicas utilizadas para la detección de colisiones en el ámbito de los videojuegos. Objetivos específicos • Definir el concepto de colisión en el mundo físico. • Descomponer los múltiples casos de colisión en el plano de los videojuegos. • Organizar los métodos de colisión según su plano espacial en el videojuego. • Detallar cada una de estas técnicas para su implementación. • Contrastar cada uno de los métodos de acuerdo con su plano espacial, género, dificultad y coste computacional. • Mostar su uso con ejemplos cotidianos y en el plano de videojuegos. 13 CAPITULO III MARCO TEORICO En el siguiente trabajo de investigación, se asumirán las soluciones con las perspectivas en función de su complejidad y el plano donde están son efectuadas, por lo tanto, en primera instancia es necesario. Primeramente, hay que usar la noción de espacio y colisiones desde un punto de vista estadístico, esto con el fin de poder tener en cuenta cuantas posibles operaciones debería realizar nuestros algoritmos, esto va cambiando, dependiendo del modelado que se le a los entidades y objetos del videojuego y su dimensión. Podemos partir de la idea de que cada objeto puede chocar con otro objeto por lo menos una vez, y que las paredes no cuenten como limitación, donde la cantidad de colisiones puede llevarse (𝑛 − 1)2 , esto se plantea desde un parte estadística-física, sin embargo, en el artículo “Collision Detection for Solid Objects” (Souto, n.d.) llega a la conclusión de que llevar esta aproximación completa al plano computación resultaría, en mayor medida en algoritmos del orden de complejidad espacial de 𝑂(𝑛2 ). Esta aproximación no solo nace de la naturaleza las colisiones, sino de la creación de un sistema de reglas físicas, como la creación de la máscara de colisiones, ya que la aproximación que se tenía en ese entonces era la construcción de una caja convexa, lo que su generación por medio de algoritmos de fuerza bruta lleva a un coste bastante extenso de cómputo, que sería la primera aproximación para resolver. 14 Por ejemplo, tomando dos casos de la misma dimensión para poder ilustrar la cantidad de colisiones a colocar, seria tomar este pequeño fragmento del videojuego Pong de Atari y el videojuego de Space Invaders de la misma compañía. Ilustración 6. Gameplay de Pong Extraído de: https://www.hiig.de/on-imitation-and-innovation-in-the-games-sector-from-pong-to-ridiculousfishing/amp/ En esta instancia del juego, podemos tener en cuenta solo hay 3 entidades durante este juego, la pelota y las dos barras blancas, donde su cantidad de colisiones varia, teniendo la pelota seis posibles colisiones, y las dos barras cada una con una colisión perfecta, puesto que la forma de modelado de su caja de colisiones es el rectángulo, por lo tanto, su ejecución seria bastante optima y veloz, debido a la forma de sus figuras. Estos casos son los más básicos de colisiones, donde podemos decir que la entidad a verificar cumple con la condición de que su forma coincide perfectamente con una forma geometría plana en el caso de dos dimensiones. 15 Ilustración 7. Gameplay de Space Invaders. Imagen extraída de: https://www.lavanguardia.com/tecnologia/20180725/451089770519/space-invaders-40aniversario-marcianitos-arcade.html Sin embargo, en esta instancia del juego Space Invaders, podemos tener en cuenta que la bala puede tener en total 48 colisiones, donde en cada instancia le tocaría calcular si ha colisionado con alguno de los 48 objetos restantes de la escena, también debemos tener en cuenta las colisiones que debe generar cada proyectil expulsado por los enemigos, donde una aproximación precisa, llevaría a una ejecución mucho más compleja, debido a la múltiple composición de sus objetos y su forma no perfecta. Por ejemplo, podemos ver cada enemigo como la unión de un rectángulo con dos líneas pequeñas rectangulares, entonces al partir cada uno podemos afirmar que habría 144 colisiones que realiza el proyectil disparado con la nave, para una colisión perfecta, por lo tanto, surgieron algoritmos para realizar estas aproximaciones. Los algoritmos para descubrir una colisión en juegos de 2D dependen del tipo de formas que deseamos colisionar (Ej.: Rectángulo, Círculo). Por lo general se tendrá una manera sencilla que cubre la figura, gracias a esto la colisión no será impecable píxel a píxel. 16 Decimos que dos elementos colisionan cuando uno de ellos se sobrepone a otro. En ese instante, debemos disparar una "señal" y tratar esa colisión consecuentemente, impidiendo el movimiento si es un sólido, restando vida si es un enemigo, etc. Todo va a depender del tipo de colisión. La simplificación es clave para todo tema de representar la realidad en un PC y en el descubrimiento de colisiones no es menos. Ilustración 8. Sprite de ejemplo. Extraído de: https://i.blogs.es/b030d8/naves/1366_2000.png Al descubrir colisiones entre los anteriores sprites es requisito simplificar su geometría. Para eso, se procede a envolverlos en figuras geométricas sencillas, tal es así que sea simple de descubrir si colisionan o no. 17 Ilustración 9. Sprites con caja de colisión rectangular. Extraído de: https://i.blogs.es/3e7536/naves2/1366_2000.png Ahora, se van a usar dos rectángulos rojos para representar a las naves: si estos colisionan entonces las naves colisionan. Si se aprecia bien, se notará que hay situaciones en las que no lo harán, puesto que estos rectángulos no representan fielmente a las naves, ya que se está representando una figura irregular con una regular, como se muestra a continuación Ilustración 10. Sprite con caja de colisión rectangular poco precisa. Extraído de: https://geeks.ms/cfsfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jbosch/colision_5F00_rectangulo.png 18 Ilustración 11. Mal uso de las cajas de colisiones para una figura. Extraído de: https://i.blogs.es/65b693/sin-20titulo-2/1366_2000.png En este ejemplo, precisamente se está utilizando la figura equivocada para describir las colisiones. Por este motivo, hay que utilizar una conjunción de figuras geométricas para ser más leales a la realidad. Un rectángulo se puede representar por medio de un punto p (x, y) 2D que representa la coordenada de la esquina inferior izquierda, un valor w que representa el ancho y un valor h que representa la altura. Por otro lado, para representar un círculo vamos a usar un punto p que representa el centro de este y un valor r que define el radio. Ilustración 12. Representación del rectángulo y circulo en el plano. Extraído de: https://i.blogs.es/2001da/representacion/1366_2000.png Existen numerosas técnicas de detección de colisiones entre sprites. Lo más fácil y eficiente es utilizar rectángulos. 19 Para que un rectángulo está colisionando con otro, tienen que cumplirse 4 condiciones. Definiendo dos rectángulos r1 y r2, diremos que estos colisionan si: 1. El lado derecho de r1 es mayor que el lado izquierdo de r2. 2. El lado izquierdo de r1 es menor que lado derecho de r2. 3. El lado superior de r1 es mayor que el lado inferior de r2. 4. El lado inferior de r1 es menor que el lado superior de r2. De cumplirse estas cuatro condiciones, se concluirá que existe una colisión entre r1 y r2. Ahora resta traducir lo anterior a código… Entender si dos círculos están colisionando es mucho más fácil: si la suma de sus radios es más grande que la distancia entre sus centros, entonces hay una colisión. Fundamentalmente hay que llevar a cabo dos tareas: calcular la distancia entre sus centros y corroborar si esta es menor a la suma de sus radios. Para calcular la distancia entre dos puntos lo necesario es agregar una función “distancia entre centros” a nuestra clase punto que reciba otro punto y devuelva la distancia entre ellos. La forma de calcular la distancia entre dos puntos es con el teorema de Pitágoras. 20 Ilustración 13. Código en Python de ejemplificación. Extraido de: https://www.genbeta.com/desarrollo/teoria-decolisiones-2d-conceptos-basicos La inquietud que se nos podría plantear en este punto es: ¿Qué tipo de recubrimiento elegir? Vemos que la detección de colisiones entre rectángulos es más rápida, ya que en la de círculos hay raíces cuadradas de por medio, las cuales son siempre algo más lentas. Pero los círculos tienen una gran ventaja frente a los rectángulos, y es que admiten rotaciones. Ilustración 14. Caja de colisiones poco precisas en figuras irregulares. Extraído de https://i.blogs.es/fd51a5/naves31/1366_2000.png 21 Por mucho que rotes un círculo sigue siendo un círculo. En el momento en que rotes un rectángulo, estos cálculos tan simples ya no valen. Una posible solución es comprobar todos los pasos intermedios con distancia menores al tamaño de los objetos. Así, se asegura que no se atraviese ningún sólido. Ilustración 15. Representación de Búsqueda Lineal. Extraído de: https://i.blogs.es/d44569/linear/1366_2000.png Este método incrementa exponencialmente el número de comprobaciones de colisión a hacer por cada objeto, haciendo un mayor uso de recursos Esta otra solución consiste en trazar una circunferencia que tenga de diámetro la distancia desplazada y como centro el medio del vector del desplazamiento. Ilustración 16. Representación de la búsqueda binaria. Extraído de: https://i.blogs.es/3b072a/binario1/1366_2000.png Si este círculo delimitador no colisiona con ningún objeto, entonces no existe colisión. Por otro lado, si existe una colisión, procedemos a dividir el espacio en dos circunferencias y comprobar si existe colisión en alguna de ellas. 22 Ilustración 17. Segunda representación de la búsqueda binaria. Extraído de: https://i.blogs.es/3869e0/binario1/1366_2000.png Seguimos dividiendo la circunferencia donde encontremos la colisión y desechando la otra hasta que encontremos la colisión. Ilustración 18. Colisión de la búsqueda binaria. Extraído de: https://i.blogs.es/ bf951a / binario3/1366_2000.png Como vemos, la búsqueda binaria reduce muchísimo las comprobaciones que tenemos que realizar, permitiendo una gestión eficiente de los recursos. Es evidente que la implementación de algoritmos de detección de colisión crece en cuanto a complejidad cuando pasamos de 2D a 3D. En esta sección empezaremos explorando las técnicas básicas y culminaremos en las avanzadas, todo esto considerando, por un lado, la optimización y la precisión de detección y, por otro, el rendimiento de la máquina. Las técnicas más sencillas surgieron a finales del siglo pasado con videojuegos como Doom o Super Mario 64. El primero, plasmando un pseudo 3D por medio del 23 conocido Raycasting (la técnica que más nos ocupará en este documento) y, el segundo, cambiando estándares en la industria de videojuegos gracias a su innovador estilo (no nos detendremos demasiado tiempo en este). Antes de introducir estos métodos de colisión, pondremos en contexto lo que es trabajar con tres dimensiones extendiendo algunas de las técnicas vistas con superficies de colisión a su análogo con volúmenes de colisión. VOLÚMENES DE COLISIÓN PLANOS La intersección de un punto con un plano se determina de una manera sencilla mediante la ecuación del plano: 𝐴𝑥 + 𝐵𝑦 + 𝐶𝑧 + 𝐷 = 0 (1) Para ello es necesario considerar un plano cartesiano con 3 dimensiones definidas por los ejes x, y, z. Sea 𝑃(𝑥0 , 𝑦0 , 𝑧0 ) un punto cualquiera en el espacio, si las coordenadas de P satisfacen (1), entonces se dice que existe una colisión entre P y el plano: 𝐴𝑥0 + 𝐵𝑦0 + 𝐶𝑧0 + 𝐷 = 0 ESFERAS 24 Para esferas, se dice que hay una colisión con un punto 𝑃(𝑥𝑝 , 𝑦𝑝 , 𝑧𝑝 ) si la distancia entre este y el centro de la circunferencia 𝐶(𝑥𝑐 , 𝑦𝑐 , 𝑧𝑐 ) es menor o igual al radio r de la circunferencia: La ecuación de la circunferencia viene dada por: (𝑥 − 𝑥𝑐 )2 + (𝑦 − 𝑦𝑐 )2 + (𝑧 − 𝑧𝑐 )2 = 𝑟 2 (2), donde r representa el radio. Entonces existe una colisión si: ||𝑃 − 𝐶|| ≤ 𝑟 ||(𝑥𝑝 , 𝑦𝑝 , 𝑧𝑝 ) − (𝑥𝑐 , 𝑦𝑐 , 𝑧𝑐 )|| ≤ 𝑟 Para dos esferas 𝐶1 y 𝐶2 , la colisión se calcula en base a la distancia entre el centro de cada una. Si dicha longitud es menor o igual a la suma de los radios de las circunferencias, entonces se tiene una colisión: ||𝐶1 − 𝐶2 || ≤ 𝑟1 + 𝑟2 ||(𝑥𝑐1 , 𝑦𝑐1 , 𝑧𝑐1 ) − (𝑥𝑐2 , 𝑦𝑐2 , 𝑧𝑐2 )|| ≤ 𝑟1 + 𝑟2 25 CAJAS Usualmente se conocen como Bounding Boxes. Dado que en este caso se tiene una mayor complejidad, es habitual utilizar dos tipos de cajas para la detección de colisiones: i. Axis-Aligned Bounding Boxes (AABB): Su orientación nunca cambia y va alineada a los ejes x, y, z manejados en el espacio de la simulación. Así, los cálculos son relativamente sencillos. ii. Oriented Bounding Boxes (OBB): Su orientación varía con la rotación del cuerpo a recubrir. Esto proporciona una mayor precisión que las AABBs, a pesar de que el algoritmo es más complejo y exigente con la máquina. Más adelante trataremos el tema de las Bounding Boxes, ya que la manera de utilizarlas dependerá, entre otras cosas, de la técnica de colisión en cuestión. RAYCASTING. 26 Ilustración 17. Extraído de: https://stackoverflow.com/questions/47239797/ray-casting-with-different-height-size Tiempo atrás, las computadoras no poseían la capacidad de manejar motores 3D en tiempo real. Esto dio lugar a técnicas como el Raycasting, el cual es aplicado a mapas 2D para generar una perspectiva en 3 dimensiones (Vandevenne, 2004). Esta técnica tuvo como pionero a Scott Roth y fue la primera solución al problema de representar gráficos 3D, siendo implementada en videojuegos como Doom o Wolfenstein 3D dada su favorable velocidad de cómputo. 27 EJEMPLARES. En la Tabla 1 se muestran los ejemplares más destacados del Raycasting en la época: Título Año Wolfenstein 3D 1992 Vista previa Ilustración 19. Extraído de: https://wolfenstein.fandom.com/es/wiki/Wolfenstein_3D 28 Doom 1993 Ilustración 20. Extraído de: https://www.nintendo.es/Juegos/Programasdescargables-Nintendo-Switch/DOOM-1993--1610001.html Duke Nukem 1996 Ilustración 21. Extraído de: https://as.com/meristation/2016/09/29/album/1472889780_000001.html Tabla 1. Ejemplares del Raycasting. Para aplicar esta técnica se requiere un elemento que cumpla la función de láser apuntador, el cual se extienda hacia el infinito hasta que, eventualmente, colisione con algún cuerpo sólido. Dicho elemento se conoce como ray. 29 Ilustración 18. Puntero laser Extraído de: https://www.aao.org/eye-health/news/puntero-laser-peligroso-lesiones-oculares Formalmente, un ray está compuesto por dos vectores: el vector posición 𝑟𝑎𝑦𝑝𝑜𝑠 , que marca el punto de partida del ray; y el de dirección 𝑟𝑎𝑦𝑑𝑖𝑟 , que empieza en la cabeza del vector posición y es el que se extiende en una determinada dirección. Cuando el ray se halla dentro de un cuerpo (colisiona), este último es dibujado con un tamaño relativo a la distancia hasta el observador. Para efectuar esta detección se emplea un ciclo que aumenta la posición de 𝑟𝑎𝑦𝑑𝑖𝑟 hasta que este colisione o hasta que se llegue a la distancia límite de detección establecida. En cualquiera de estos casos, se procede a detener el ciclo y calcular la distancia entre 𝑟𝑎𝑦𝑝𝑜𝑠 y 𝑟𝑎𝑦𝑑𝑖𝑟 (Vandevenne, 2004). 30 COLISIONES. A continuación, se exponen distintos tipos de colisión que se pueden tratar por medio de Raycasting. Para aquellos que van acompañados de su algoritmo en C++ para su implementación, cabe aclarar que son requeridas las siguientes clases y estructuras a fin de representar todos los elementos que intervienen en el sistema de detección: - Ray: Posee los atributos de tipo Vector3D denominados position y direction para representar a 𝑟𝑎𝑦𝑝𝑜𝑠 y a 𝑟𝑎𝑦𝑑𝑖𝑟 , respectivamente. - SphereVolume: Posee el atributo de tipo float denominado radius, que define el radio (en pixeles) de la esfera. - RayCollision: Esta clase tiene como utilidad abstraer las colisiones, dando acceso al punto en el que esta se produjo (collidedAt de tipo Vector3) y al objeto en cuestión (node del tipo especificado al crear una instancia). de base para representar el ray, los volúmenes de colisión, las matrices de transformación, entre otros. Ello será obviado en este documento para efectos de simplicidad. Sin más que decir, los siguientes son los tipos de colisión a estudiar: PLANOS. Siempre que el vector normal al plano en cuestión no sea paralelo a 𝑟𝑎𝑦𝑑𝑖𝑟 (𝑟𝑎𝑦𝑑𝑖𝑟 ∙ 𝑝𝑙𝑎𝑛𝑜𝑛𝑜𝑟𝑚𝑎𝑙 ≠ 0), se garantiza que habrá una intersección en algún punto P del espacio. En primer lugar, definamos las variables que siguen: - p: punto de intersección de 𝑟𝑎𝑦𝑑𝑖𝑟 con el plano. - t: distancia que va desde 𝑟𝑎𝑦𝑝𝑜𝑠 hasta p. - 𝒑𝒍𝒂𝒏𝒐𝒏𝒐𝒓𝒎𝒂𝒍: vector normal al plano en p. 31 - 𝒑𝒍𝒂𝒏𝒐𝒅 : el término independiente de la ecuación del plano D. En otras palabras, sea la ecuación del plano 𝐴𝑥 + 𝐵𝑦 + 𝐶𝑧 + 𝐷 = 0, el valor 𝑝𝑙𝑎𝑛𝑜𝑑 equivale a D. Otro modo de obtener este valor es a través del 𝐷 = ||𝑝𝑙𝑎𝑛𝑜𝑛𝑜𝑟𝑚𝑎𝑙 ∙ 𝑄||, donde Q es cualquier punto sobre el plano. Ilustración 19. Proyección normal del plano Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf En primer lugar, se calcula la distancia t que va desde 𝑟𝑎𝑦𝑝𝑜𝑠 hasta p: 𝑡= −(𝑟𝑎𝑦𝑝𝑜𝑠 ∙ 𝑝𝑙𝑎𝑛𝑜𝑛𝑜𝑟𝑚𝑎𝑙 + 𝑝𝑙𝑎𝑛𝑜𝑑 ) 𝑟𝑎𝑦𝑑𝑖𝑟 ∙ 𝑝𝑙𝑎𝑛𝑜𝑛𝑜𝑟𝑚𝑎𝑙 Finalmente, buscamos el punto en el cual se efectúa la intersección. Este viene dado de la siguiente manera: 𝑝 = 𝑟𝑎𝑦𝑝𝑜𝑠 + 𝑡(𝑟𝑎𝑦𝑑𝑖𝑟 ) 32 ESFERAS. Ilustración 20. Proyección hacia una esfera de un rayo. Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf La detección de colisiones con esferas por este método se basa en el centro y radio de esta. Nuevamente, definimos algunas variables: - p: punto que define si hay intersección. - p’: punto de intersección con la esfera. - 𝒔𝒄𝒆𝒏𝒕𝒓𝒐 : centro de la esfera. - 𝒓: radio de la esfera. - d: distancia desde 𝑟𝑎𝑦𝑝𝑜𝑠 hasta p’. - dir: vector que inicia en 𝑟𝑎𝑦𝑝𝑜𝑠 y culmina en 𝑠𝑐𝑒𝑛𝑡𝑟𝑜 . El primer paso consiste en verificar si existe o no una intersección del ray con la esfera. Para ello, calculamos dir: 𝑑𝑖𝑟 = 𝑠𝑐𝑒𝑛𝑡𝑟𝑜 − 𝑟𝑎𝑦𝑝𝑜𝑠 𝑝 = 𝑟𝑎𝑦𝑝𝑜𝑠 + (𝑑𝑖𝑟 ∙ 𝑟𝑎𝑦𝑑𝑖𝑟 )𝑟𝑎𝑦𝑑𝑖𝑟 33 Si |𝑝 − 𝑠𝑐𝑒𝑛𝑡𝑟𝑜 | ≤ 𝑟, entonces hay una colisión en un punto p’. Para calcularlo, hallamos, en segundo lugar, la distancia d: 𝑑 = ||𝑝 − 𝑟𝑎𝑦𝑝𝑜𝑠 || − √𝑟 2 − ||𝑝 − 𝑠𝑐𝑒𝑛𝑡𝑟𝑜 || 2 Finalmente, el punto de colisión será: 𝑝′ = 𝑟𝑎𝑦𝑝𝑜𝑠 + 𝑑(𝑟𝑎𝑦𝑑𝑖𝑟 ) Algoritmo (C++): El Algoritmo 1 determina si existe una colisión entre un ray una la esfera cuya matriz de transformación es recibida por parámetros. De ser así, retorna verdadero; caso contrario, retorna falso. El algoritmo recibe por parámetros al ray r, a la matriz de transformación de la esfera worldTransform, al volumen de la esfera volume y a la instancia de colisión collision. 34 Ilustración 21. Código en C++ de detección de colisión hacia una esfera. Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf CAJAS. i. AABB: Cuando trabajamos con AABBs estamos trabajando con cajas que poseen una orientación fija basada en los ejes x, y y z en cuestión, de modo que cada caja poseerá un ancho, un largo y un alto. Para efectos de practicidad, asociaremos estos atributos con los ejes x, y y z, respectivamente; y, como es de esperarse, definiremos las siguientes variables: 35 - 𝒃𝒐𝒙𝒄𝒆𝒏𝒕𝒓𝒐 : centro de la esfera. - dir: vector que va desde 𝑟𝑎𝑦𝑑𝑖𝑟 hasta 𝑏𝑜𝑥𝑐𝑒𝑛𝑡𝑟𝑜 . - 𝒔𝒊𝒛𝒆𝒙 : mitad del ancho de la caja. - 𝒔𝒊𝒛𝒆𝒚 : mitad del largo de la caja. - 𝒔𝒊𝒛𝒆𝒛 : mitad del alto de la caja. Ilustración 22. Rayo proyectado hacia caja, Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf En caso de que sólo deseemos saber si existe alguna colisión entre el ray y la caja, el proceso a seguir consiste en calcular el vector dir definido previamente y verificar, por medio de la magnitud de sus componentes, si se da una colisión. 𝑑𝑖𝑟 = 𝑟𝑎𝑦𝑑𝑖𝑟 − 𝑏𝑜𝑥𝑐𝑒𝑛𝑡𝑟𝑜 36 Ahora, se compara la magnitud de los componentes del vector dir con los valores 𝑠𝑖𝑧𝑒𝑥 , 𝑠𝑖𝑧𝑒𝑦 , 𝑠𝑖𝑧𝑒𝑧 de la siguiente manera. Si: - |𝑑𝑖𝑟𝑥 | ≤ 𝑠𝑖𝑧𝑒𝑥 , - |𝑑𝑖𝑟𝑦 | ≤ 𝑠𝑖𝑧𝑒𝑦 y - |𝑑𝑖𝑟𝑧 | ≤ 𝑠𝑖𝑧𝑒𝑧 , entonces existe una colisión del ray con la caja AABB. En caso de que se deseemos conocer el punto exacto de colisión, el proceso es un poco menos sencillo. Como es sabido, las cajas poseen 6 caras, no obstante, no es necesario realizar los cálculos con cada una de ellas, puesto que podemos descartar aquellas 3 que se encuentren más lejanas a 𝑟𝑎𝑦𝑑𝑖𝑟 , una por cada eje con el objetivo de reducir la carga computacional. Por ejemplo, si el ray se dirige hacia arriba, sabemos que intersectará antes con la cara inferior de la caja, por lo que descartaremos inmediatamente la cara superior. Llevando esto a todas las caras de la caja, haremos 3 descartes y el número de comparaciones será la mitad. 37 Ilustración 23. Proyección normal de colisión hacia la caja. Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf En la Ilustración 24 se observa una representación de esta situación en 2D en la cual, habiendo descartado las caras superior e izquierda (y quedando con la cara inferior y la derecha), notamos que el punto de colisión se dará en aquella cara cuyo eje es el más lejano a 𝑟𝑎𝑦𝑝𝑜𝑠 . Extrapolaremos esto a una situación 3D, pero antes vamos a definir las siguientes variables: - 𝒃𝒐𝒙𝒎𝒊𝒏: vértice con las coordenadas de menor valor de la caja. - 𝒃𝒐𝒙𝒎𝒂𝒙 : vértice con las coordenadas de mayor valor de la caja. - p: punto de colisión del ray con la caja. - dist: suponiendo que se han descartado 3 caras de la caja, esta variable indica la mayor distancia desde 𝑟𝑎𝑦𝑝𝑜𝑠 hasta el plano de las caras restantes que se halla más lejano. 𝑏𝑜𝑥𝑚𝑖𝑛 = 𝑏𝑜𝑥𝑐𝑒𝑛𝑡𝑟𝑜 − (𝑠𝑖𝑧𝑒𝑥 𝑖 + 𝑠𝑖𝑧𝑒𝑦 𝑗 + 𝑠𝑖𝑧𝑒𝑧 𝑘) 𝑏𝑜𝑥𝑚𝑎𝑥 = 𝑏𝑜𝑥𝑐𝑒𝑛𝑡𝑟𝑜 + (𝑠𝑖𝑧𝑒𝑥 𝑖 + 𝑠𝑖𝑧𝑒𝑦 𝑗 + 𝑠𝑖𝑧𝑒𝑧 𝑘) 38 Calculamos los siguientes 3 valores: - - - 𝑏𝑜𝑥min 𝑥 −𝑟𝑎𝑦𝑝𝑜𝑠 𝑥 𝑟𝑎𝑦𝑑𝑖𝑟 𝑥 𝑏𝑜𝑥min 𝑦 −𝑟𝑎𝑦𝑝𝑜𝑠 𝑦 𝑟𝑎𝑦𝑑𝑖𝑟 𝑦 𝑏𝑜𝑥min 𝑧 −𝑟𝑎𝑦𝑝𝑜𝑠 𝑧 𝑟𝑎𝑦𝑑𝑖𝑟 𝑧 si 𝑟𝑎𝑦𝑑𝑖𝑟 𝑥 > 0, ó si 𝑟𝑎𝑦𝑑𝑖𝑟 𝑦 > 0, ó si 𝑟𝑎𝑦𝑑𝑖𝑟 𝑧 > 0, ó 𝑏𝑜𝑥max 𝑥 −𝑟𝑎𝑦𝑝𝑜𝑠 𝑥 en caso contrario, 𝑟𝑎𝑦𝑑𝑖𝑟 𝑥 𝑏𝑜𝑥max 𝑦 −𝑟𝑎𝑦𝑝𝑜𝑠 𝑦 𝑟𝑎𝑦𝑑𝑖𝑟 𝑦 𝑏𝑜𝑥max 𝑧 −𝑟𝑎𝑦𝑝𝑜𝑠 𝑧 𝑟𝑎𝑦𝑑𝑖𝑟 𝑧 en caso contrario y en caso contrario, y asignamos el mayor de ellos a la variable dist. Si 𝑑𝑖𝑠𝑡 < 0 entonces significa que el ray apunta en dirección opuesta a la caja, por lo que no existe una colisión. De no ser así, calculamos p (esto no garantiza una colisión): 𝑝 = 𝑟𝑎𝑦𝑝𝑜𝑠 + 𝑑𝑖𝑠𝑡(𝑟𝑎𝑦𝑝𝑜𝑠 ) Si se cumple que: - 𝑝𝑥 ≤ 𝑚𝑎𝑥𝑥 , - 𝑝𝑥 ≥ 𝑚𝑖𝑛𝑥 , - 𝑝𝑦 ≤ 𝑚𝑎𝑥𝑦 , - 𝑝𝑦 ≥ 𝑚𝑖𝑛𝑦 , - 𝑝𝑧 ≤ 𝑚𝑎𝑥𝑧 y - 𝑝𝑧 ≥ 𝑚𝑖𝑛𝑧 , Entonces existe una colisión del ray con la caja en p. Por supuesto, lo anterior puede ser aplicado igualmente con un valor épsilon si se busca aceptar colisiones con cierto margen de error, debido a que, para ojos del jugador, los cálculos no necesitan tener una precisión del 100%, en especial cuando tratamos con números reales. 39 Algoritmo (C++): El Algoritmo 2 lleva los pasos que vimos previamente a código. El algoritmo recibe por parámetros al ray r, a al centro de la caja boxPos, al tamaño de la caja boxSize y a la instancia de colisión collision. Ilustración 24. Algoritmo en C++ de detección hacia cajas. Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf 40 ii. OBB: Manejar colisiones con OBBs por medio de Raycasting es mucho más complejo que con AABBs. Esto se debe principalmente a que el ray y el OBB poseen ejes de referencia distintos, lo cual obliga a implementar otro tipo de estrategias para calcular las colisiones. Visto lo anterior, ¿es posible llevar ambos elementos a un mismo “mundo”? La respuesta es sí, y ello requiere pasar del sistema de ejes por defecto (world space) a un sistema pasajero de coordenadas (local space). La solución que aquí se trata consiste en transformar temporalmente la posición y dirección del ray, de modo que estos pasen a compartir la orientación del OBB en cuestión y a fin de convertir esta situación en una que aplique los ya tratados AABBs. Esto se logra usando el inverso de la matriz de transformación del ray. Algoritmo (C++): El Algoritmo 3 recibe por parámetros al ray r, a la matriz de transformación de la caja transform, al volumen de la caja volume y a la instancia de colisión collision. Ilustración 25. Código en C++ de detección de colisión hacia caja OBB. Extraído de: https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/1raycasting/Physics%20%20Raycasting.pdf 41 SUPER MARIO 64 Super Mario 64 logró revolucionar la industria de los videojuegos, rompiendo con la tradición de la saga de Mario llena de ejemplares estilo plataforma 2D. En 1996 fue lanzado al mercado un juego de mundo abierto en 3 dimensiones, el cual, a diferencia de los ya tratados Doom, Duke Nukem y Wolfenstein 3D, sí implementó un sistema de colisión 3D. Las superficies del mapa se basaban en triángulos con cierta orientación, a partir de la cual se definía si se trataba de una pared, techo, suelo, etc. Ilustración 26. Mapa representado en sus polígonos. Extraído de: https://youtu.be/6hUK1Wbajt4 Cualquier figura 2D en el juego puede ser representada por medio de triángulos, como se observa debajo. Ilustración 27. Caj de colisión del piso de Super Mario 64. Extraído de: https://youtu.be/UnU7DJXiMAQ 42 En adición, Super Mario 64 hizo uso de volúmenes de recubrimiento para las figuras 3D en conjunto con algoritmos capaces de detectar y responder ante colisiones entre volúmenes con volúmenes y volúmenes con superficies. Ilustración 28. Representación de una colisión en sus formas elementales. Extraído de: https://youtu.be/CLNSw11RQCQ Para examinar las colisiones en el contexto planteado podemos recurrir a los métodos vistos anteriormente en la sección de Volúmenes de Colisión. No nos detendremos en este punto dado que es necesario conocer técnicas más avanzadas encaminadas a trabajar en ambientes de mayor complejidad e, incluso, optimizar los métodos que hemos estudiado hasta el momento. 43 Luego del salto tecnológico al plano de las tres dimensiones, muchas de las técnicas se implementaron a esta nueva dimensión. Muchas de las técnicas avanzadas plantean el uso de estructuras de datos y nociones matemáticas de mayor complejidad, primeramente, tomamos en cuenta las estructuras de datos para facilitar los cálculos de las mencionadas cajas de colisiones, esta vez orientadas a sus volúmenes, donde era necesario cálculos más rápidos a formas más poligonales, donde ahora esta seria nuestro objeto de colisión, lo que hace que nuestro numero de combinaciones oscile números inmensos, por ejemplo, tomando en cuenta la caja de colisiones del videojuego Counter Strike Global Offensive: Partiendo de que, en una situación normal del juego, podemos partir de que, si hay 9 personas vivas, y cada uno disparar tres balas, cada parte de la caja de colisiones podría tener alrededor de 27 colisiones, formando en total que sobre tu personaje se calculan 324 colisiones, y si lo llevamos al plano de todo el juego en función de los personajes, serian 1620 colisiones. 44 Debido a estas reglas nacen unas nuevas aproximaciones voraces y uso de técnicas antes más ineficientes para solucionar a estos problemas, donde en el libro “Game Progamming Patterns” podemos encontrar dichas asumpciónes (Nystrom, 2014) : • Creación de cajas convexas, donde su resultado, no sea una forma geométrica regular tridimensional, gracias al avance en procesamiento, esta solución era más viable. • Clasificación de objetos en estacionarios y dinámicos. • Reducción de colisiones, en función de su probabilidad. • Uso de estructuras dinámicas que ayuden a simular un plano especial. Gracias a estas aproximaciones, podemos partir de la creación de una mejora de los algoritmos de AABB, que resulta en un algoritmo de OBB, donde se orientan en el uso de estructuras dinámicas como arboles binarios parcialmente ordenados con condición inferior, donde se almacena la partición volumétrica de cada parte de nuestro polígono y luego apoyarnos en el teorema de SAT para lograr detectar las colisiones. Esta solución se construyó haciendo uso de los conceptos de recursividad y programación dinámica para la construcción de las cajas y geometría planar para hallar las colisiones. Igual que las soluciones anteriores, iremos construyendo dicha idea, primero en pasos: 1. Construir la partición por volumen de la figura de manera recursiva 2. Almacenar dichas partes en un montículo o BSP 3. Creación de la OBB 4. Dentro del juego, ejecutar el teorema de SAT cada cuadro para verificar si existe una colisión. 45 La importancia de este algoritmo reside en la precisión de este, el punto clave a entender sobre los algoritmos básicos, es el remplazo del modelo AABB a un modelo OBB, el paso número 3, del algoritmo, esta diferencia reside en que el modelo AABB al ser rotado sobre su eje debe recalcular sus dimensiones, que en el plano volumétrico puede causar grandes errores de colisiones. Ilustración 29. Falla al presentar rotación sobre su eje. Imagen extraída de: ttps://www.gamasutra.com/view/feature/3190/advanced_collision_detection_.php?print=1 A diferencia de la una caja de colisiones AABB que siempre estará creada sobre un eje sobre el cual esta se va a alinear cuando se produzca una rotación o movimiento, este constante calculo provocaría que cada segundo debiera generarse una nueva caja de colisiones, donde probablemente en ese cálculo puede fallar la colisión, o en el caso de no generarla, al momento de una rotación el volumen de la caja seria distinto al de su caja, dando fallas en las colisiones. Por ejemplo, podemos tomar en consideración un juego donde los cálculos deben ser rápidos y precisos como la franquicia de Dark Souls, el cual se caracteriza por su dificultad y frenéticos combates. Debido a esto, necesitan estar verificando constantemente golpes espontáneos y rápido, por lo que usarían un modelo similar al AABB, sin embargo, cuando un enemigo ejecute un golpe donde la espada rote lo suficiente para alterar su eje o el personaje se deslice justo en esos momentos, no se notara la colisión de manera inmediata. 46 Ilustración 30. Error ocasionado por una mala detección de colisiones del juego Dark Souls. Extraída de: https://i.kinja-img.com/gawker-media/image/upload/hhn3h9xlne9keaxosw62.gif La recomendación para este modelo parte de juegos que necesiten una precisión de calculo eficiente y no tan espontanea, géneros como los FPS hacen uso constante de este, debido a la importancia de la detección de colisión con explosiones y proyectiles a lo largo de los mapas y jugadores. Por lo tanto, primeramente, necesitamos definir el paso 1, que usaremos el concepto de OVB, que seria en este caso usando, la mejor aproximación actual es el algoritmo de O'Rourke's, su visualización seria la siguiente, con el personaje de Megaman: 47 Ilustración 31. Modelo tridimensional de Megaman.Extraída de: https://es.ssbwiki.com/wiki/Pose_de_referencia Algorítmicamente la idea detrás de la generación de una caja de convexa es la noción del concepto de “divide y vencerás”, donde dado un set de puntos que representan las coordenadas espaciales del polígono iremos usando los dos puntos más distantes en la coordenada X, y obtendremos un tercer punto que sea la distancia en Z más alta entre esos dos 48 puntos, al construir nuestra pirámide, eliminaremos los puntos internos e iremos repitiendo el proceso con los puntos seleccionados previamente. Para un mayor entendimiento de esta figura, se ingresará un fragmento de código en Python y su ejecución, donde solo se obtiene esta caja para un set de puntos en 2D, si se desea una mayor manejo y compresión, se dejará el artículo del cual fue sacado el código (Washam, 2016). Ilustración 32. Generador de la caja convexa en Python. Extraído de: https://startupnextdoor.com/computingconvex-hull-in-python/ Para este caso en particular iremos tomando la figura de Megaman, este partirá su cuerpo poligonal en dos grandes cajas convexas, el torso y las extremidades superiores, y dichas partes recursivamente las procesará para lograr genera una caja más pequeña para ese entorno, y así hasta cuando cubra la mínima en cada uno, donde quedará una caja con bastante precisión. 49 Debido a la gran extensión que cubre el algoritmo, para poder tener una mejor interpretación de este y su idea, se encuentra una implementación en el lenguaje Mathlab por el usuario chadogme en el repositorio de OptimalBB 1. Durante la ejecución del paso anterior iríamos insertando, a un montículo dichas ejecuciones, donde la raíz seria la totalidad del cuerpo poligonal, y cada división que va realizando será un hijo, donde a cada hijo se le construirá su OBB, por el fin explorativo de la investigación se asumirá que dicho algoritmo se encuentra ya construido en nuestro motor gráfico2. Si el lector desea tener una mayor exploración sobre el tema de la construcción de OBB, se le recomienda la lectura del trabajo investigativo “Oriented Bounding Box” (SCHNEIDER & EBERLY, 2003) Dando el caso anterior el siguiente árbol montículo de figura repartidas en el espacio o BSP: Ilustración 33. BSP de la partición del modelo 1 Código de la implementación del algoritmo para la creación de la caja convexa para modelos en 3D https://github.com/chadogome/OptimalOBB/tree/master/src 2 Actualmente existen una amplia cantidad de modelos matemáticos que se usan para generar una OBB, sin embargo, en la mayoría de los casos las usadas por los videojuegos vienen implementadas por los motores comerciales o privados. 50 Podemos ver el árbol de la siguiente manera: • A es el modelo en si al dividirla • B sería la primera caja vertical o • D y E serian la partición de B C sería la primera caja horizontal o F y G serian la partición de C Ya luego de haber generado cada OBB para cada entidad de nuestro juego, nos disponemos a la esencia básica de una colisión otra vez, la intersección de alguna de las cajas de colisión. Usaremos el mismo método que realizan muchas colisiones en 2D, es el teorema de SAT (Separating axis theorem), que se encarga de verificar que si al realizar una proyección de entre dos polígonos, se podría realizar una línea entre estos, si se sobreponen hay colisión. Sin embargo, en este caso contamos con una particularidad, muchos de los problemas que se encontraron a la hora de implementar este teorema (Ejes a tomar, formas de las cajas, proyecciones de ejes…) se resuelven por la naturaleza de nuestra nueva caja de colisiones, que al ser arbitrariamente ordenada y genera formas convexas para cada entidad, no es necesario verificar las condiciones anteriores, y el resultado a generar seguirá siendo una línea. 51 De igual manera para una mayor compresión se colocará un fragmento que cuente con el algoritmo enfocado a las tres dimensiones y un pequeño fragmento de este. Ilustración 34. Seudocódigo del SAT implementado en 3D Extraído de: https://gamedev.stackexchange.com/questions/44500/how-many-and-which-axes-to-use-for-3d-obb-collision-withsat Por otro lado, se dejará una implementación del código funcional en el motor grafico Unity en el lenguaje de C#, creado por el usuario Bas Emit 3 3 Enlace del código https://drive.google.com/file/d/1wXoYqQbO5TqkQ9fEgCbFQw4PL05Ap7Xu/view?usp=sharing 52 Ilustración 35. Implementación del teorema de SAT en C# Ilustración 36. Demostración correcta del código en el motor grafico de Untiy Como se puede en la esquina inferior izquierda, nos indica que no hay colisión, donde el mensaje de la consola dice “False”. 53 Ilustración 37. Demostración correcta del código en el motor grafico de Untiy En el caso contrario nos indica que, si hay colisión, se puede ver en la esquina inferior izquierda. Luego, se buscó desarrollar un sistema que aplique los conceptos de Colisión e Interacción, estos objetivos normalmente iban de la mano con la necesidad de procesar la ocurrencia de choques de la manera más efectiva y en el menor tiempo posible, ya que luego de identificar el choque lo común es tener que ejecutar una acción en consecuencia. Por esto se han buscó nuevas desarrollar técnicas que permitieran procesar grandes cantidades de posibles colisiones entre entidades en tiempos convenientemente cortos. 54 A partir de esta necesidad se planteó la idea de dividir los procesos en una etapa de “preparativos” y otra de ejecución final. Esta es la base de los algoritmos de detección de colisiones de dos fases4, compuestos por una Narrow Phase, que es la segunda fase, destinada a la detección propiamente dicha de las colisiones; y una Broad Phase, que es la primera, que tiene el propósito de simplificar lo más posible el área o espacio de evaluación, descartando grupos de datos a partir de identificadores relacionados con su posición en el espacio. La Narrow Phase de un algoritmo de dos fases se puede llevar a cabo por medio de diversas técnicas, de las cuales el particionamiento espacial (Spatial Partitioning) es una de las más representativas, efectivas y sencillas de comprender. Esta técnica permite ahorrar mucho tiempo de ejecución, ya que en lugar de evaluar cada una de todas las estadísticamente posibles colisiones que pudieron haberse producido en un instante de tiempo, categoriza las entidades evaluables por bloques de los cuales cada uno representa una sección del espacial (Gallego & Rodríguez, n.d.). Para ejemplificar la importancia de esta partición espacial, imaginemos un recipiente con esferas rebotando y chocando entre ellas. Si en un momento específico quisiéramos identificar qué esferas están chocando sin ninguna técnica especializada previa, nos veríamos en la necesidad de evaluar si existe una colisión para cada par de esferas posible, lo cual podría aumentar en gran medida su tiempo de ejecución si agregamos más esferas al recipiente, haciéndolo un método ineficiente. 4 Algoritmo de dos fases: Se basa en separar el procedimiento en una primera fase que identifica la primera solución factible (y más básica), y en una segunda fase que identifica la solución específica a partir de la básica encontrada anteriormente. https://sites.google.com/site/metodosdeprogramacionlinealdan/metodo-de-las-dos-fases 55 Por otro lado, si decidimos separar el espacio del recipiente en varias secciones, cuando decidamos evaluar las colisiones, tendremos la opción de recorrer el espacio total por medio de las secciones anteriormente establecidas, cada una con pocas esferas en su interior, y evaluar para cada sección si se producen colisiones entre los elementos que contiene. Y si la cuestión fuera evaluar las colisiones de esferas en un área específica, este razonamiento cobra aún más relevancia. En lugar de evaluar cada una de las esferas individualmente, verificar si se encuentra en esa área, y comprobar si colisiona con otra, tenemos la opción de dirigirnos directamente a la partición que nos representa esa sección del espacio, y evaluar únicamente las entidades en su interior. A partir de esta básica ejemplificación podemos evidenciar fácilmente un punto muy importante que se convierte en el fundamento de las particiones espaciales, el cual indica que “Si organizamos nuestros objetos en una estructura de datos organizada por sus localizaciones, podemos acceder a ellos mucho más rápido” (Nystrom, 2014) Ilustración 38. Ejemplo de árbol k-d (Tipo de estructura para partición espacial). Extraído de: https://www.google.com/url?sa=i&url=http%3A%2F%2Fwww.gitta.info%2FSpatPartitio%2Fen%2Ftext%2FSpatParti tio.pdf&psig=AOvVaw333wr5eMG3wgdSuk0grA9l&ust=1604629221681000&source=images&cd=vfe&ved=0CA0Qjh xqFwoTCIDRkfSr6uwCFQAAAAAdAAAAABAU Estas particiones pueden ser puesta en práctica con un ejemplo práctico bastante simple expuesto en el libro Game Programming Patterns por Robert Nystrom, en el cual busca modelar colisiones entre varios soldados en un campo amplio, para lo cual divide el campo en secciones de una cuadrícula: 56 Algoritmo (C++): Clase de la cuadrícula: Clase de soldados: 57 Nótese que cada celda de la cuadrícula es a fin de cuentas un “apuntador” hacia una unidad, por lo que el espacio estaría siendo organizado en una lista doblemente enlazada, tal que: Ilustración 39. Representación de la relación celda-unidad. Extraído de: https://gameprogrammingpatterns.com/images/spatial-partition-linked-list.png Dentro de esta estructura organizada, se evaluaría cada celda una por una, y estas manejarían las acciones entre soldados de esta manera: Ilustración 40. Código que representa el sistema de casillas. Extraído de: https://gameprogrammingpatterns.com/images/ 58 Si se decidiera evaluar las colisiones entre soldados sin una partición espacial, sería de esta forma: Nótese que ambos algoritmos de comparación realizan exactamente los mismos pasos (con sintaxis distinta), pero con la diferencia de que el último realiza estas comparaciones entre cada uno de los soldados y todos los demás, mientras que con la implementación de la partición espacial descartamos todos los soldados que estén en celdas distintas al que se está evaluando, y solo se comparan posiciones con aquellos que estén lo suficientemente cerca para que se produzca una colisión (en la misma celda). Las particiones espaciales pueden implementarse por medio de diversas estructuras de datos, pero las más comunes son: 59 Grid: También conocida como cuadrícula, un grid es un arreglo de datos que puede presentarse en cualquier forma. En esta estructura los datos no necesitan ser adyacentes entre ellos. Ilustración 41. Representación de un grid. Extraído de: https://gameprogrammingpatterns.com/images/spatial-partition-grid.png BSP (Binary Space Partitioning): Es un método para realizar dos subdivisiones del espacio de manera recursiva, de forma que estas dos nuevas particiones tengan aproximadamente el mismo número de elementos. Ilustración 42: Representación de una BSP Extraído de: https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Binary_space_partition.png/600pxBinary_space_partition.png 60 Quadtree: O árbol cuaternario, empieza con todo el espacio como una única partición. Para este espacio se designa un límite de elementos, y en el momento en que el número de elementos supere el límite admisible, el espacio en el cual fue superado se parte en 4 secciones. Este proceso se realiza de manera recursiva hasta que cada una de las secciones generadas poseen menos elementos que el límite designado. Ilustración 42: Representación de una BSP Extraído de: https://opendsaserver.cs.vt.edu/ODSA/Books/CS3/html/_images/PRexamp.png Respecto a colisiones, el árbol cuaternario está destinado principalmente a un ambiente en dos dimensiones, si se desea implementar este tipo de partición en tres dimensiones, se deben manejar los datos un Octree, que es básicamente el análogo directo para 3D de un QuadTree. En lugar de particiones de a 4 secciones cada una, se realizan particiones de a 8 volúmenes cada una. Además de la dimensión adicional, el manejo de este árbol no se distancia mucho del manejo de un QuadTree. 61 Ilustración 42: Representación de un Octree. Extraído de: https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Octree2.svg/1200px-Octree2.svg.png 62 CAPITULO IV CONCLUSIONES A lo largo de la investigación hemos visto desde las primeras ideas de la lo que los primeros ingenieros de sistemas tenían sobre modelar el concepto de colisión, como desde el uso de múltiples teoremas matemáticos lo único que necesitaron fue mejorar sus maneras de crear estas colisiones, desde los modelos de caja perfecta hasta los modelos de caja convexa o OBB. Primeramente, podemos concluir que no existe un algoritmo mejor en cuanto a tiempos de ejecución a grandes rasgos, este solo depende de nuestra necesidad. Aunque su eficiencia y tiempo de ejecución varié de manera significativa entre ellos, actualmente con la potencia de procesamiento que tenemos, hace que muchos algoritmos que hace mucho tiempo fueran inviables como el Modelo RayCasting – OBB, las mejoras realizadas a estos y el aumento del poder de procesamiento llevaron a que hoy en día podamos ejecutar la mayoría de estos algoritmos en nuestros videojuegos de una manera “rápida” en nuestro juego, donde la variante es su precisión. Consecuentemente con la idea anterior, podemos afirmar que los algoritmos residen en su precisión y necesidad, es decir, como ingenieros de sistemas debemos de primera mano entender el contexto en el cual deseamos realizar y verificar las colisiones. Por ejemplo, al realizar un juego de deportes como FIFA, seria completamente inviable la generación de una caja de colisiones AABB, donde tanto los jugadores como el balón estarán en constante movimiento, teniendo contacto físico entre ellos y el balón recibiendo distintos tipos de efecto para realizar algunos tiros al arco o a otros jugadores, un modelo tan rápido, pero poco preciso generaría una mala experiencia de juego y posibles fallos no intuitivos. 63 Gracias a esto podemos afirmar, la importancia del análisis del contexto a la hora de realizar una solución para un problema dado, enfatizando el área de planificación y maquetado de un sistema de soluciones, en vez de realizar directamente la codificación, ya que se pudo ver a lo largo del desarrollo de esta investigación que múltiples motores gráficos comerciales como Unity o Unreal Engine, vienen con ciertos modelos creados como el OBB y el AABB, sin embargo, tú mismo puedes realizar tu propio modelo de colisión y en cual enfocarte para tu videojuego. Para concluir, pudimos ver de manera general como grupo la importancia de conocer todas las soluciones posibles que disponemos a la hora de generar una solución a un problema, y que no existe una única respuesta a nuestro problema, sino múltiples maneras de abordarlo y abstraerlos. En el campo de los videojuegos y aprendizaje grupal pudimos ver como se reúnen todos los conocimientos que hemos tenido a lo largo del desarrollo de la carrera, además de aprender una nueva serie de conceptos que nos permite un mejor desarrollo como profesionales. 64 CAPITULO V BIBLIOGRAFIA Gallego, F., & Rodríguez, S. (n.d.). Detección de colisiones 3D. Test. Nystrom, B. (2014). Game Programming Patterns (G. Be (ed.)). https://gameprogrammingpatterns.com/ SCHNEIDER, P., & EBERLY, D. (2003). Oriented Bounding Box. https://www.sciencedirect.com/topics/computer-science/oriented-bounding-box Souto, N. (n.d.). Video Game Physics Tutorial - Part II: Collision Detection for Solid Objects. https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solidobjects Vandevenne, L. (2004). Raycasting. https://lodev.org/cgtutor/raycasting.html Washam, J. (2016). Computing Convex Hull in Python. https://startupnextdoor.com/computing-convex-hull-in-python/ Daddu. (2018). SM64 Janky Hitboxes (4:39). https://www.youtube.com/watch?v=CLNSw11RQCQ&feature=youtu.be&ab_channel=da ddu UncommentatedPannen. (2017). Walls, Floors, & Ceilings (37:22). https://www.youtube.com/watch?v=UnU7DJXiMAQ&feature=youtu.be&ab_channel=Un commentatedPannen Josh65536. (2017). SM64DS: Mesh Colliders Part 2: Collision Detection (9:26). https://www.youtube.com/watch?v=6hUK1Wbajt4&feature=youtu.be&ab_channel=Josh 65536 Physics - Raycasting Introduction. (n.d.). 1–17. Ford, C. M. (2017). Virtuosos on the Screen: Playing Virtual Characters Like Instruments in Competitive Super Smash Bros. Melee. Proceedings of the 2017 CHI Conference on Human Factors in Computing Systems. Bobic, B. N. (2009). Advanced Collision Detection. AdvancED ActionScript 3.0 Animation, 1–47. https://doi.org/10.1007/978-1-4302-1609-4_1 Washam, J. (2016). Computing Convex Hull in Python. https://startupnextdoor.com/computing-convex-hull-in-python/ Adrian. (2013). Teoría de colisiones 2D: Conceptos básicos. https://www.genbeta.com/desarrollo/teoria-de-colisiones-2d-conceptos-basicos 65 View publication stats