Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Comprobar visibilidad de objetos

Iniciado por marcode, 15 de Enero de 2008, 11:41:29 PM

« anterior - próximo »

marcode

¿Sabéis donde puedo encontrar una función optimizada que compruebe si un boundig box está dentro del volumen de visualización de la cámara?. O alguien que ya la tenga implementada...

(Lógicamente es para determinar si hay que dibujar un objeto o no.)
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]

BeRSeRKeR

Yann Lombard mencionó hace tiempo un método que parece ser muy rápido. Aquí tienes el hilo, más abajo pone el código.

Yo no lo he probado así que no sé cuán eficiente será, pero si Yann lo dice... :lol:

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

senior wapo

No especificas si es un AABBOX o un BBOX genérico.

Asumiendo que te refieres a una caja alineada con los ejes de coordenadas:

Para cada plano del fustrum (6) miras la distancia de la esquina del cubo más próxima al plano. Si sale negativa, el cubo no es visible.
Si además comparas la esquina más lejana, puedes saber si invade parcialmente o está completamente dentro.

Las esquinas potencialmente más cercanas y más lejanas son aquellas que están en la diagonal de la caja más paralela a lanormal del plano.

Dado que conoces la orientación del BBOX (siempre alineados a los ejes) y que el plano de separación permanece fijo durante todo el fotograma, puedes calcular la diagonal (esquinas) a usar usando los signos de la normal del plano.

El código de Yann parece que hace eso aunque creo que no entiende el concepto y se limita a contar la mecánica. Por cierto, NO es necesario transformar el frustrum como dice él, ya que lo puedes extraer de la propia matriz de proyección. Hay un paper con código para Direct3D y OpenGL, googlea.

Googlea BoxOnPlaneSide, está en el código fuente del Quake1 o el 2 (comprobando las dos esquinas), asi como en el culling del motor Haddd1 (sólo comprueba una esquina).

También hay un paper en español que leí una vez y lo explica, supongo que buscando culling+diagonal+pdf saldrá.

Si usas bbox de orientación arbitraria me temo que te toca probar todas las esquinas o montarte un mecanismo para averiguar la diagonal. Creo que en este caso te rentaría más una esfera de centro el de la caja y radio la mitad de una diagonal.

marcode

Pues parece que no ha puesto el código, sino el pseudo.

Me va a tocar traducirlo, entenderlo, devanarlo, adaptarlo, y codificarlo como no encuentre algo mejor, algo ya hecho  :cry:

Esperemos que valga la pena, mientras si alguien sabe donde hay una función que le pueda hacer un copy/paste directamente pues mejor.


pd: acabo de ver tu mensaje senior, voy a leerlo.
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]

marcode

Vale, parece que me va a tocar estudiar.

En principio es un cubo orientado con los ejes y con el mismo ancho-alto-largo.

Es decir, que más o menos con esta función me bastaría, conociendo la posicion/orientacion/frustum/view de la cámara que podría ir en una matriz y sabiendo la posición y el tamaño del cubo.

bool EsVisible( MATRIX matCam, POINT Pos, float Tam)

{
    // es visible o no
}


Si existe por ahí esta función o una parecida, o alguien la tiene hecha, me permitiría reservar energías para otros quebraderos de cabeza que tengo pendientes.

si no... pues a joderme y a hacerlo toca.
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]

BeRSeRKeR

Creo que el documento al que se refiere senior wapo es

Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix

de Gil Gribb y Klaus Hartmann.

El sistema del que habla es el que utilizamos nosotros en Haddd/Jade.

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

xeex

hola, yo hice algo asi hace un tiempo,claro tendrias que repetilo para 4 puntos:


bool estaenfrustum;

bool esta(float x,float y,float z)
  {
    //traslacion
    x=x-xpos;
    y=y-ypos;
    z=z-zpos;    
   
    //rotacion en eje y
    float auxx1;
    float auxy1;
    float auxz1;
    float roty=float(yrot*3.14159265358979/180.0);      
    float cosy=float(cos(roty));
    float seny=float(sin(roty));
   
    auxx1= x*cosy   +z*seny;
    auxy1=y;
    auxz1= -x*(seny)+z*cosy;
   
    x=auxx1;
    y=auxy1;
    z=auxz1;
   
    float auxx;
    float auxy;
    float auxz;
    float rotx=float(xrot*3.14159265358979/180.0);      
    float cosx=float(cos(rotx));
    float senx=float(sin(rotx));
   
    auxx=x;
    auxy=y*cosx-z*senx;
    auxz=y*senx+z*cosx;
   
    x=auxx;
    y=auxy;
    z=auxz;

    float nearplane      =   nearp;
    float farplane       =   farp;
    float leftplane      =  -1.0;
    float rightplane     =   1.0;
    float bottomplane    =  -1.0;
    float upplane        =   1.0;
    float ladosuperior   =   -(upplane/nearplane)*(z);
    float ladoinferior   =    (upplane/nearplane)*(z);
   
    float ladoizquierdo  =    (rightplane/nearplane)*(z);
    float ladoderecho    =   -(rightplane/nearplane)*(z);
    bool  esta           =   false;
   
    if((y<=ladosuperior&&y>=ladoinferior)&&(x>=ladoizquierdo&&x<=ladoderecho))    
     {
      return true;
      estaenfrustum=true;
     }
    else
     {
      return false;
      estaenfrustum=false;
     }
}


x,y,z son las coordenadas del punto a comprobar si esta o no en el volumen.
xpos,ypos,zpos son las cordenadas de la camara.
xrot e yrot son las rotaciones respectivas que se han hecho en los ejes x e y,para el efecto de girar la camara hacia arriba y abajo e izquierda y derecha.

mmm y eso...era eso o no?
adios.

tamat

Cita de: "xeex"hola, yo hice algo asi hace un tiempo,claro tendrias que repetilo para 4 puntos:
falso, ya que es posible que los cuatro puntos esten fuera del frustrum y sin embargo el objeto esté dentro, como por ejemplo si miras un objeto muy grande de cerca.
Por un stratos menos tenso

xeex

tienes toda la razon...aunque, ese es el uniko caso o no?.
me retracto...lo que hace la funcion es devolver si un punto esta o no en el volumen de vision...aunque solo bastaria modificarlo un pokito y ya...
adios.






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.