Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Engordar los triangulos

Iniciado por Lord Trancos, 01 de Enero de 1970, 01:00:00 AM

« anterior - próximo »

Lord Trancos

                                Uso la siguiente función (convenientemente adaptada a Delphi) del ejemplo de "Picking" del DX SDK8 para determinar si un rayo atraviesa un triangulo. El problema es que a veces los rayos me pasan entre dos poligonos (por la juntas que los unen).



BOOL CMyD3DApplication::IntersectTriangle( const D3DXVECTOR3& orig,

                                      const D3DXVECTOR3& dir, D3DXVECTOR3& v0,

                                      D3DXVECTOR3& v1, D3DXVECTOR3& v2,

                                      FLOAT* t, FLOAT* u, FLOAT* v )

{

   // Find vectors for two edges sharing vert0

   D3DXVECTOR3 edge1 = v1 - v0;

   D3DXVECTOR3 edge2 = v2 - v0;



   // Begin calculating determinant - also used to calculate U parameter

   D3DXVECTOR3 pvec;

   D3DXVec3Cross( &pvec, &dir, &edge2 );



   // If determinant is near zero, ray lies in plane of triangle

   FLOAT det = D3DXVec3Dot( &edge1, &pvec );

   if( det < 0.0001f )

       return FALSE;



   // Calculate distance from vert0 to ray origin

   D3DXVECTOR3 tvec = orig - v0;



   // Calculate U parameter and test bounds

   *u = D3DXVec3Dot( &tvec, &pvec );

   if( *u < 0.0f || *u > det )

       return FALSE;



   // Prepare to test V parameter

   D3DXVECTOR3 qvec;

   D3DXVec3Cross( &qvec, &tvec, &edge1 );



   // Calculate V parameter and test bounds

   *v = D3DXVec3Dot( &dir, &qvec );

   if( *v < 0.0f || *u + *v > det )

       return FALSE;



   // Calculate t, scale parameters, ray intersects triangle

   *t = D3DXVec3Dot( &edge2, &qvec );

   FLOAT fInvDet = 1.0f / det;

   *t *= fInvDet;

   *u *= fInvDet;

   *v *= fInvDet;



   return TRUE;

}



He intentado modificar la funcion para que se considerará que el triangulo es mas grande... pero no lo consigo (solo me hace cosas raras...)

Supongo que tengo que modificar estas lineas, pero no se como:

   if( *u < 0.0f || *u > det )

   if( *v < 0.0f || *u + *v > det )


que dios os pague con muchos hijos cualquier ayudita que me lleve en la direccion correcta xD

                               
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.

fiero

                                ¿Te refieres a que no detecta ni uno ni otro? Yo uso la misma función y nunca me pasa eso...                                
www.videopanoramas.com Videopanoramas 3D player

Lord Trancos

                                Exacto, me refiero a que el rayo pasa entre las juntas (edges o como quieras llamarlos) que unen a los poligonos.                                
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.

Mars Attacks

                                Así a ojo prueba a cambiar los < por <= y que conste que sólo lo digo porque me aburro y pasaba por aquí XD                                

samsaga2

                                Supongo que el error viene por la precision limitada de decimales. A mi me pasaba con mi programa de supercutreraytracing.

Del algoritmo que presentas no me acabo de enterar como funciona, pero para arreglar esos fallos se suele dar un pequeña cantidad de margen de acierto, yo que se, por ejemplo 0.005.
                               

fiero

                                Pues no sé porqué, pero yo tengo una pequeña diferencia respecto a tu función. La saqué de DX7 pero no sé si cambié algo o era así originalmente. La diferencia es lo del signo del determinante:

   

BOOL CObjeto3D::IntersectaTriangulo(D3DXVECTOR3 orig,D3DXVECTOR3 dir
                                   ,D3DXVECTOR3 v0,D3DXVECTOR3 v1,D3DXVECTOR3 v2
                                   ,
float* t,float* u,float* v )
{
   
// Find vectors for two edges sharing vert0
   D3DXVECTOR3 lado1 = v1 - v0;
   D3DXVECTOR3 lado2 = v2 - v0;

   
// Begin calculating determinant - also used to calculate U parameter
   D3DVECTOR pvec;
   VectorCross(&pvec,&dir,&lado2);

   
// If determinant is near zero, ray lies in plane of triangle
   
float det=VectorDot(&lado1, &pvec );

   D3DVECTOR tvec;
   
if(det>0)
   {
       tvec=orig-v0;
   }
   
else
   {
       tvec=v0-orig;
       det=-det;
   }

   
if(det<0.0001f) return FALSE;

   
// Calculate U parameter and test bounds
   *u=VectorDot(&tvec,&pvec);
   
if(*u<0.0f || *u>det) return FALSE;

   
// Prepare to test V parameter
   D3DVECTOR qvec;
   VectorCross(&qvec,&tvec,&lado1);

   
// Calculate V parameter and test bounds
   *v=VectorDot(&dir,&qvec);
   
if(*v<0.0f || *u+*v>det) return FALSE;

   
// Calculate t, scale parameters, ray intersects triangle
   *t=VectorDot(&lado2,&qvec);
   
float fInvDet = 1.0f / det;
   *t *= fInvDet;
   *u *= fInvDet;
   *v *= fInvDet;

   
return TRUE;
}
                               
www.videopanoramas.com Videopanoramas 3D player

ethernet

                                fiero como haces para poner el codigo asi en los foros. case s es igual q en flipcode xD                                

ethernet

                                POr si alguien no se habia enterado (yo no xD) mirad este codigo. Thx neliñuelo :ojo:

http://www.stratos-ad.com/forums/viewtopic...opic=49&forum=7                                

BeRSeRKeR

                                Hay otro conversor que pasa de varios tipos de archivos de código (C/C++/Cg/ASM/Pas/Java, y muchos más) a HTML. Lo podéis encontrar en su http://webcpp.sourceforge.net/index.php">page de sourceforge...

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

NeLo

                                De nothing ethernethy :*
                               
Drowning deep in my sea of loathing

Lord Trancos

                                Weno, weno, weno.... parece ser que lo de cambiar los < y > por <= y >=, funciona bastante bien :riendo:

Pero me he dado cuenta de que algunos de los problemas que tenia eran causa de que la susodicha funcion ignora las colisiones con los triangulos que no "miran" hacia el origen del rayo....

la version modificada de fiero parece que intenta solucionar esto, pero no se si es que cometo algun error en otra parte o que,... pero no consigo que me funcione correctamente.

A todo esto, alguien me podria explicar que demonios es el "determinante" ese :lengua:

Anoche estuve intentando comprender la funcion, pero mi nivel de mates no da para mucho... :triste:
                               
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.

BeRSeRKeR

                                Pues mirando el code, deduzco que "det" nos dice si el rayo es paralelo o va a intersectar en la cara posterior del plano sobre el que descansa el triángulo, casos en los cuales no habría intersección.

De esta forma tenemos que con la línea

VectorCross(&pvec,&dir,&lado2);

se está calculando la normal al plano formado por los vectores dirección del rayo y una de las aristas del triángulo. Con esto obtenemos la normal del plano que forman estos dos vectores (de forma que conocemos la orientación relativa entre los dos planos; el del triángulo y el que acabamos de calcular). Sabiendo esa normal ya podemos saber si el rayo descansa sobre el triángulo (det == 0), si está por la cara posterior del triángulo (det < 0) o si está por encima (det > 0) por lo que en este último caso sí habría posibilidad de intersección...

Espero que sea correcto :sonriendo:

Saludos

_________________
Visita:
La web de http://www.planetquake.com/digitalys">DiGiTALYS
La web del motor http://run.to/illusion3d">Illusion3D

[ Este Mensaje fue editado por: BeRSeRKeR el 2002-09-06 14:45 ]                                
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Lord Trancos

                                Gracias. Empiezo a vislumbrar la luz al final del tunel :ojo:
                               
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.

Lord Trancos

                                Vaya.... pues he vuelto a probar la funcion de fiero, y ahora si que me funciona bien :loco:....

en fins,... gracias a todos :ojo:
                               
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.






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.