Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





¡Ayuda! :)

Iniciado por BeRSeRKeR, 01 de Enero de 1970, 01:00:00 AM

« anterior - próximo »

BeRSeRKeR

                                Hola a todos.

Bueno, como la mayoría sabéis estoy programando con un colega un motor 3D.

Hasta ahora todo el trabajo ha sido de render cosa con lo que estoy habituado y no ha habido excesivos problemas. El problema llega ahora que estamos a punto de afrontar todo el tema de las colisiones (en lo cual soy un novato :sonriendo:).

Resulta que tenemos lo que es el nivel y funciona todo muy bien. La geometría del nivel se maneja a través de un sistema BSP/PVS a través del cual recojo todas las faces potencialmente visibles, las desgloso en faces solidas y faces translúcidas, las ordeno por shader para evitar en lo máximo los cambios de estado (tanto de render como de textura) y las mando al procesador de shaders el cual transforma la geometría y entonces renderiza (primero las faces solidas y despues las translúcidas).

Pero ahora tenemos que meter los modelos, es decir, los objetos decorativos, los personajes, etc...o sea, todo aquello susceptible a ser movido. Aunque el problema no radica ahí exactamente. La cosa es que si renderizo los modelos y el nivel por separado es evidente que se producirán fallos a la hora de calcular el blending, es decir, si renderizo primero el nivel y después los modelos, es realmente sencillo (de echo ocurrirá :sonriendo:) que a través de un cristal no se viera el modelo que debería verse. Si lo hago al contrario, es decir, primero renderizo los modelos y despues el nivel pues es más complicado que se produzca una situación así pero también es probable...se me ocurre el caso de un modelo translúcido (porque ha pillado el item de la invisibilidad :ojo:) a través del cual no se ve el nivel...

Viendo todos estos problemas llegué a la conclusión (bastante rápidamente) de que tendría que meter todo en el mismo saco (nivel y modelos) y desglosar, al igual que hacia con el nivel, las faces solidas de las translúcidas, procesar a través de los shaders y pintar...pero claro, esto presenta un inconveniente y es que ya no puedo utilizar las funciones de transformación del API (SetTransform en el caso de Direct3D) para mover, rotar, escalar, etc los modelos. Así que supuse que todo esto lo tendría que hacer "a mano", o sea, transformar cada vértice de la geometría (sólo de los modelos ya que el nivel sería estático y ya está en coordenadas de mundo) por la matriz de transformación correspondiente...pero entonces pensé que esto debía ser bastante cargante para el motor aunque por otro lado supuse que así es como se hacía a la hora de la detección de colisiones. Es por esto que pido vuestra ayuda para ver si puedo solucionar todo esto de la mejor forma posible, es decir, ¿es una locura transformar los vértices uno por uno por su matriz de transformación?...estos vértices ya transformados me servirían después para calcular las colisiones ¿no?...aunque también deduzco que para el tema de la detección de colisiones primero transformaríamos a nivel de bbox (o lo que utilicemos), veríamos si hemos colisionado y si es así transformaríamos los vértices lo cual sería mucho más barato en terminos de proceso ya que no transformaríamos los vértices de todos los modelos...sólo los que perteneciesen a los modelos con los que hubiese colisión...

Entended que nunca he afrontado esta parte de un motor 3D por lo que estoy casi en blanco :sonriendo:

¡Un saludo y gracias!
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

soynegativo

                                Bueno, esta claro que lo de construir engines de 0 no es solo una locura nuestra (mia y de la gente que se encarga de mi proyecto)


Respecto a tu problema:
El problema de colisiones y el mantener la lista de vertices transformados es un problema (como siempre) de numeros: "cuantos vertices tiene tu modelo?" y "como de finas son tus colisiones?" y "cuando vas a calcular las colisiones?"

Cuantos vertices tiene tu modelo?
Bueno, yo he trabajado en un engine3D en java (puro) y tenia que mantener la lista de vertices transformados (de local a mundo) para determinar la luz , visibilidad y cosas asi, bueno, el hecho de guardar la malla de puntos no era relativamente grave , y estamos hablando de lenguaje interpretado, asi que en principio no te asustes por eso...
recuerda que de todos modos, el tener las transformaciones de los modelos te puede ayudar en algunas optimizaciones (al menos, a mi me ayuda mucho en openGL).

Como de finas son tus colisiones? y cuando vas a calcular las colisiones?
Bueno, yo tengo toda la escena en un arbol de Bounding Spheres para los modelos móviles, entonces yo lo que intento es primero resolver las colisiones (fisicas, elasticas, predecibles) a priori, determinando por cada pareja de colisionadores que queremos tener en cuenta en que momento del frame se chocarán, donde estarán en el choque y cuanto tiempo les quedará en ese frame para moverse, asi soluciono las colisiones a priori ( no me hace mucha gracia los calculos del tipo: ya nos hemos chocado, tenemos un objeto dentro de otro y tenemos que ver hacia donde han salido los objetos) , bueno el proceso es "algo" mas complejo, pero basicamente muy por encima es asi. Finalmente, sabiendo donde estan las esferas al final del frame, ya tenemos la transformación concreta de ese colisionador.
Ya se que parece un poco raro, pero he trabajado principalmente en engines3d en soft puro sin uso de librerias opengl o directx y me molesta un poco el hecho de que el uso de esas librerias corte la iniciativa del tipo "yo quiero eliminar mis caras ocultas y hacer mi culling yo solito", y luego verte atrapado en un punto en el que es necesario pensar como si no tuvieras aceleradora.

perdon por lo largo ,pero estoy un poco empanado (y espesito) hoy :sonriendo:


                               
aniel Rodriguez Millan
Java Development Team

BeRSeRKeR

                                Hola...gracias por responder.

¿Lo que quieres decir es que no debería preocuparme por el tema de transformar vértice a vértice?. Los modelos que hagamos puede que tengan unas 2000 faces máximo más o menos aunque la mayoría tendrán menos.

En lo referente a las colisiones, en principio serán a nivel de bspheres (o tal vez bboxes) aunque claro si ha habido colisión, habrá que detectarla a nivel de faces...pero supongo que sólo en el caso de por ejemplo a la hora de detectar el punto donde ha colisionado un disparo porque en el caso de colision modelo/modelo pues con las bspeheres podria ser suficiente (aunque claro imagina un misil que tiene que pasar entre las piernas de un personaje :sonriendo:)

Pero bueno eso es algo que deberemos afrontar más adelante (no dentro de mucho) aunque si es cierto que es bueno ir planificándolo ya para después no encontrarse con sorpresas :sonriendo:.

Por ahora me valdría con saber si el tema de transformar vértice a vértice para posicionar los objetos en el lugar adecuado es correcto o no...aunque como bien dices, en el mundo de los engines por software esto es así y se acabó :sonriendo:

Un saludo.

_________________
BeRSeRKeR
http://www.planetquake.com/digitalys">DiGiTALYS TEAM

[ Este Mensaje fue editado por: BeRSeRKeR el 2002-03-28 19:31 ]                                
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

_Grey

                                Pues si,BeRSeRKeR!  tines que meter los poligonos opacos de decorado , y de objetos "independientes" , y dejar para el final los poligonos con transparencias , tanto los del decorado como los de los objetos "independientes".

No , no es una locura transformar los vertices uno a uno, se pierde eficiencia, es mejor que lo haga DirectX por si la aceleradora lo acelera, pero no es extraño hacerlo "a mano", de todas formas no entiendo por que dices que no puedes usar el SetTransfor().... puedes hacer un DrawIndexPrimitive() o DrawPrimitive() , cambiar la matriz por la que se transforma y haccer otro, es mas, si utilizas modelos con partes solidas, es mas efeciente esto que no transformar "a mano".

Respecto a las colisiones, todo y que las e tocado, no e profundizado en el tema, pero te dire que en un engine antiguo con el que trastee me hice unas funciones para detectar colisiones perfectas, como es logico todo tiraba muy lento , no hace falta discutir que lo mejor es usar (bounding (box || sphere)), y si necesitas mas precision usar lo que te cuento y si existe colision seguir con las de detencion perfectas.

Espero que te sirva de ayuda!

Saludos.                                

BeRSeRKeR

                                Hola _GRey. Gracias por responder.

Cuando decía lo de que no puedo utilizar las transformaciones de la API es porque si meto todas las faces en el mismo buffer y ordeno por shader resulta que tendré faces que pertenecen al nivel y al modelo en un mismo grupo...es por eso que si aplico una transformación con SetTransform estaré transformando la geometría con la misma matriz...tanto para el modelo como para el nivel lo cual es incorrecto.

Un saludo
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

_Grey

                                Si ,si ordenas las faces tendras que transformar a mano.

Me siento culpable por decir que es mas rapido hacer las transformaciones y llamar a drawindexprimitive().... en un principio es asi... pero no siempre si se trata de pocos objetos pero con muchos vertices se hace si se trata de unos cuantos objetos y no demasiadas caras , entonces transforma "a mana", he leido que tendras bichejos de unas 2000 faces???? pues nada se hace "a mano", son pocas, y bla bla bla...

Chao.                                

Drácula

                                Yo siempre transformo a pelo los vértices, precisamente para calcular colisiones, y no he tenido problemas de velocidad.

El problema de las transparencias es ...¡muy complejo! Hay un pdf en NVidia que explica cómo renderizar correctamente transparencias sin importar el orden de los objetos.

Respecto a las colisiones, yo utilizaba en mi primer motor las colisiones perfectas, es decir triángulo-segmento, y es evidente de que dependen totalmente del nº de vértices. Pero leí hace unos meses documentos sobre sistemas de detección rápida de colisiones que pueden ayudarte. Tendrás que mirar en flipcode, porque no tengo apuntado el link.

Suerte con tu motor. Yo estoy desarrollando el mio de nuevo, pronto subiré una versión que sólo maneja sprites 2D para que la gente que empieza pueda hacer algo!                                
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

BeRSeRKeR

                                Hey gracias Drácula.

La verdad es que el tema de las transparencias tiene su miga si. Ya digo que cuando se trataba de pintar los polígonos del nivel pues no era problema...pintaba primero los polígonos sólidos y después desactivaba la escritura en el zbuffer y pintaba los transparentes. El problema se presenta ahora que tengo que pintar los modelos que van por separado. Y ahora encima me acabo de percatar que hay otro problema más y es que no puedo meter vértices del nivel y de modelos en el mismo buffer porque ¡¡tienen distinto FVF!!...así que ya vés...bueno le echaré un vistazo al documento del que hablas sobre las transparencias.

Un saludo.
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

KILE

                                Solo quería hacer una aclaración sobre lo de la detección de colisiones. En principio como es evidente si aplicamos Bouding Volumes (Lo más correcto en el 99% de los casos) nos podemos decantar por 3 de los volumenes más usados Esferas, Cubos o elipsoides (O cilindros) Yo he implementados todos los anteriores en el motor y estoy trabajando en un algoritmo que determine que mejor envoltura le conviene a un objeto dependiendo de los vertices que contiene para hacerlo en tiempo de carga. Lo que quería decir es que segun he leido lo que dijo drácula de que la colision ha hacía de segmento a triangulo, pienso que lo hará previa comprobación del BVolume porque sino es algo impracticable en un mundo con un nivel de geometría medio-alto. El método que yo uso es un pseudo  BSegmento-BVolumen. Me explico, si tenemos por ejemplo una esfera y un bbox y queremos detectar la colision entre ambos. No basta con coger y detectar despues de haber movido la esfera, si está dentro del bbox, sino que lo que hay que hacer es algo pare cido a:
NewPosition=OldPosition+Direction*Speed;
If CollisionVolumenSegment(OldPosition,NewPosition,BBox) then
      colisiona();

Es decir, que hay q  tomer el segmento formado por las dos esferas, pero no solament el segmento sino todo el volumen que forma (Una especia de pildora en este caso) que  básicamente y a lo bruto sería detectar la esfera inicial, la esfera final y el cilindro que une  ambos centros y va en la dirección del vector que une sus centros.
 Luego está el tema de las transformaciones de estos volumenes. Siendo una esfera es evidente q es muy rápido pero siendo un bbox no tanto x q tenemos q transformar más vertices, aunque de este tema hay varis public aciones que explican como hacerlo con gran velocidad (Entre ellas el Graphics Gemms III creo).
 Por último como dice B3rS3rK3r hay que detectar la colision a nivel de triangulo aunque tambien hay muchos algoritmos para hacer esto más rápido, el otro día sin ir más lejos se me ocurrio una forma de descartar c aras de un modelo rodeado por un BBox para mi juego y es mirar la normal de la cara del BBox ocn la que colisiona la esfera e ir descartando en base a esta normal y la de la face que estamos re corriendo así solamente recorremos todas las caras, pero sin hacer el test en todas, slamente una simple comprob ación de la normal.
   Si teneis alguna duda más ac erca de colisiones me lo decis porque ahora estoy bas tante liado mirando articulos sobre este tema y a ver si os puedo ayudar para no pegar las ostias q me he pe gado yo en algunas cosas.
  Un saludo :lengua:                                

_Grey

                                Solo una cosa, desactivar el ZBuffer para pintar los poligonos con trasparencias, para librarte de ordenarlos, no te sirvira...

Si te fijas, veras que algunos poligonos que tendrian que estar detras se ven delante, por el nivel alpha que tienen! yo ya lo probe ... y me lleve un chasco XP

Saludos.                                

BeRSeRKeR

                                No si yo no desactivo el ZBuffer para pintar los polígonos transparentes sólo desactivo la escritura en el zbuffer, es decir

m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

que sí soluciona el problema del orden en que se rendericen las faces transparentes...

Un saludo

_________________
BeRSeRKeR
http://www.planetquake.com/digitalys">DiGiTALYS TEAM

[ Este Mensaje fue editado por: BeRSeRKeR el 2002-03-30 22:35 ]                                
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

mallrat

                                BeRSeRKeR, supongo que _Grey se refiere también a que lo que haces de desactivar la escritura en Z (aunque es mejor hacerlo) no te soluciona nada, no creo que se refiera a desactivar también la lectura ya que entonces se verían las cosas transparentes incluso detras de las paredes. Claro que en realidad si que te soluciona por lo menos el caso de las transparecias que se pintan con suma al no importar el orden en ese caso.                                

BeRSeRKeR

                                Claro, es que la transparencia de los polígonos la hago a través de additive blending...porque hace lo que necesito. Aunque también utilizo alpha blending pero sólo para faces "multicapa" en las que un de ellas a lo mejor tiene una textura (con un canal alpha) a través de la cual ha de verse la capa inferior...pero eso no produce problemas de blending (siempre y cuando se utilice en situaciones como la que he mencionado)

Un saludo.
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

_Grey

                                Exactamente, como dice mallrat, me refiero a que desactivando la escritura del ZBuffer no te salva de ordenar los polis... por lo menos usando alpha blending.

Saludos.                                

DrDelete

                                En los Proceedings de las GDC2001 hay un paper que a lo mejor te interesa:

http://www.gdconf.com/archives/proceedings...01/ratcliff.doc                                






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.