Subido por Frysat castellon

Mtodosyaproximacionesimplementadasporlosvideojuegosparaunaptimadeteccindecolisiones

Anuncio
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
Descargar