Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: Lord Trancos en 01 de Enero de 1970, 01:00:00 AM

Título: Engordar los triangulos
Publicado por: Lord Trancos en 01 de Enero de 1970, 01:00:00 AM
                                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

                               
Título: Engordar los triangulos
Publicado por: fiero en 01 de Enero de 1970, 01:00:00 AM
                                ¿Te refieres a que no detecta ni uno ni otro? Yo uso la misma función y nunca me pasa eso...                                
Título: Engordar los triangulos
Publicado por: Lord Trancos en 01 de Enero de 1970, 01:00:00 AM
                                Exacto, me refiero a que el rayo pasa entre las juntas (edges o como quieras llamarlos) que unen a los poligonos.                                
Título: Engordar los triangulos
Publicado por: Mars Attacks en 01 de Enero de 1970, 01:00:00 AM
                                Así a ojo prueba a cambiar los < por <= y que conste que sólo lo digo porque me aburro y pasaba por aquí XD                                
Título: Engordar los triangulos
Publicado por: samsaga2 en 01 de Enero de 1970, 01:00:00 AM
                                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.
                               
Título: Engordar los triangulos
Publicado por: fiero en 01 de Enero de 1970, 01:00:00 AM
                                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;
}
                               
Título: Engordar los triangulos
Publicado por: ethernet en 01 de Enero de 1970, 01:00:00 AM
                                fiero como haces para poner el codigo asi en los foros. case s es igual q en flipcode xD                                
Título: Engordar los triangulos
Publicado por: ethernet en 01 de Enero de 1970, 01:00:00 AM
                                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                                
Título: Engordar los triangulos
Publicado por: BeRSeRKeR en 01 de Enero de 1970, 01:00:00 AM
                                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 page de sourceforge...

Saludos
                               
Título: Engordar los triangulos
Publicado por: NeLo en 01 de Enero de 1970, 01:00:00 AM
                                De nothing ethernethy :*
                               
Título: Engordar los triangulos
Publicado por: Lord Trancos en 01 de Enero de 1970, 01:00:00 AM
                                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:
                               
Título: Engordar los triangulos
Publicado por: BeRSeRKeR en 01 de Enero de 1970, 01:00:00 AM
                                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 DiGiTALYS
La web del motor Illusion3D

[ Este Mensaje fue editado por: BeRSeRKeR el 2002-09-06 14:45 ]                                
Título: Engordar los triangulos
Publicado por: Lord Trancos en 01 de Enero de 1970, 01:00:00 AM
                                Gracias. Empiezo a vislumbrar la luz al final del tunel :ojo:
                               
Título: Engordar los triangulos
Publicado por: Lord Trancos en 01 de Enero de 1970, 01:00:00 AM
                                Vaya.... pues he vuelto a probar la funcion de fiero, y ahora si que me funciona bien :loco:....

en fins,... gracias a todos :ojo: