Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Colision directX

Iniciado por Sagan, 22 de Enero de 2007, 01:51:54 PM

« anterior - próximo »

Sagan

Hola a todos. Me gustaría saber como puedo realizar las colisiones para mi aplicación.
Estoy creando mi propio motor gráfico en directX con C# y lo que trato de hacer es moverme con una camara a través de una habitación y no chocar ni con las paredes ni con los objetos que hay en la habitación.

He leido parte de lo que hay en el foro de este tema pero necesito algo mas adaptado a directX. Básicamente me gustaría tener un ejemplo de como se extrae la Bounding esfera o si se puede crear ésta sin tener ninguna malla como es mi caso, que en realidad solo tengo un punto que es la posición de la camara.

Luego necesito saber como detectar que la esfera colisiona con el resto de objetos. Es que no tengo claro como se accederia a los vertices de esta boundingSphere y a los de las mallas ni como se aplacaria el algoritmo. Gracias a todos.

senior wapo

La esfera no tiene vértices, la defines como el centro del objeto y su radio. En tu caso para la cámara usa un radio al azar, por ejemplo, radio 1. Cuando pruebes colisiones y veas que te queda muy cerca de los objetos, lo aumentas a ojo hasta que quede bien al probar.

Si la distancia del centro del objeto a la pared es menor o igual al radio pues ha habido colisión con la pared. Si la distancia del centro de un objeto (como pueda ser la cámara) al centro de otro (por ejemplo una mesa) es menor o igual a la suma de sus radios hay colisión.

Antes de mover la cámara a una nueva posición compruebas si en la nueva posición hay colisión con algo (comparas su esfera contra las de todos los objetos) y solo mueves la cámara si no hay colisión con ninguno.
En el caso de objetos que envuelvan la cámara (paredes y suelos de la habitación) te limitas a calcular distancia de la posición de la cámara al plano que contiene la pared teniendo en cuenta que un plano es infinito y la pared se acaba en las esquinas.

Para calcular el volumen que ocupa un objeto que sea una malla, miras todos sus vertices y te quedas con los valores minimos y maximos en los ejes x,y,z.

El punto intermedio entre la mayor X y la menor X es la componente X del centro. Lo mismo para la Y y la Z. El radio será la distancia del centro a un vertice imaginario formado por los tres valores maximos (el mayor X el mayor Y y el mayor Z).

Este es el método más rudimentario para hacer colisiones pero como estás aprendiendo, no dejes que te compliquen con palabrejas raras (árboles bsp, octrees y demás).

[EX3]

Las cajas de colision tambien son un sistema rudimentario y facil de implementar y combinandolo con la colision de esferas se podria optimizar quizas un poco a la vez que lograr mas eficiencia pienso, utilizamos una caja para identificar colision a gran escala del objeto y si existe dicha colision comprobar colisiones menores con el metodo de la esfera que es mas preciso.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Sagan

La verdad que me habeis dado algunas ideas y os lo agradezco. Ahora estoy con la creación de la esfera y no se como hacerla. Parece que hay varias posibilidades:

-Mesh esfera = Mesh.Sphere(device, 1f, 10, 10); // no se muy bien que son los dos ultimos parametros.

-float radio = Geometry.ComputeBoundingSphere(gStream,
                   _malla.NumberVertices, _malla.VertexFormat,
                   out tempCenter);// *_scale;

-Crear yo mismo la esfera con el vertexBuffer ( no tengo ni idea del algoritmo )

Para el tema de las colisiones cual se usa???? teniendo en cuenta que la esfera la necesitare visible en modo malla para depurar pero luego invisible cuando ponga su centro en el centro de la camara para realizar colision en una habitación no cuadrada y con objetos ¿ cual es la mejor opcion ? gracias

SkyNetBCN

Yo tengo el mismo problema que Sagan (que conseguí resolver de un modo un poco rupestre). En mi caso las boundingBox/boundingSpheres no me sirvieron de nada, porque no hay ninguna boundingP... que tenga la forma de un mapa lleno de habitaciones (no todas las paredes son rectas...), pasillos, puertas, etc...

Si encuentras una manera de hacer eso con bounding.... estaría bien que la colgases para echarle un vistazo...  :D

Salud2!!

[EX3]

Tambien pienso, agraciados que sois los que programais en un lenguaje tan popular como C++, por que no os dejais de darle vueltas a la tortilla y os haceis con un motor de fisicas gratuito como Newton u otro cualquiera de los que existen. Lograreis implementar colisiones muy logradas y sin mucho esfuerzo. Ojala tuviese yo implementaciones de motores de fisicas 2D para Visual Basic 6.0, todavia temo el momento cuando llegue la hora de implementar la fisica, aun siendo basica y en solo 2D, de mi motor :lol:

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

WipR7

Una forma sencilla (si no buscas grandes resultados) es lanzar un rayo con d3dxintersect en la direccíon en la que se meve la camara y si la distancia es muy pequeña no dejar que siga.

marcode

casi que lo más sencillo y práctico que puedes hacer es crear funciones (o usarlas si ya las tienes) que comprueben colisiones entre cajas, esferas y polígonos (todos con todos). No hace falta que los modeles, porque son imaginarios, a menos que quieras verlos para depurar o por curiosidad. Sencillamente basta una matriz para describirlos, porque en ella tienes la posición, la orientación (para el caso de las cajas) y la escala.

A cada objeto le asignas uno u otro bounding, excepto a los que colisionen por póligonos que serán aquellos que requieran precisión y no sean demasiado complejos, por ejemplo los muros, para estos tendrás que pasar a la función de colisión la geometría del propio modelo.

Tendrás a veces que asignar varios, de manera que se aproxime a su entorno. Para un coche pueden servir un par de cajas, y para un humano una esfera para la cabeza, y unas cajas para tronco y extremidades.

Cuando ya tienes las funciones implementadas y los boundings asociados a cada modelo o a cada parte del modelo. Ahora para cada par de objetos que compruebes usa las funciones correspondientes. Por ejemplo, para comprobar la colisión entre la cámara y el muro, se deberá usar la función que comprueba entre la esfera y una serie de polígonos (los mismos que componen los muros).

O si quieres saber si hay colisión entre una espada con un personaje se comprobaría el BoundingBox que tiene asociado la espada con cada uno de los boundings que componen el personaje. Si le has definido con 50 esferas por poner un ejemplo, pues se sabrá con bastante exactitud en qué parte del cuerpo ha colisionado. Si no hace falta mucha precisión pues basta con una esfera.

Pero no hace falta que hagas la esfera, simplemente objetos asociados de una clase (CBoundingSphere) que describa su posición y su radio o una matriz 3d, y que tenga las funciones de comprobación con otros tipos de boundings o con series de polígonos.

vaya charla, espero que te sirva de orientación.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.