2016-06-06 3 views
2

J'ai mis en œuvre l'algorithme d'intersection Möller-Trumbore Ray-Tri comme suit;Algorithme d'intersection Möller-Trumbore Ray-Tri

Note: J'ai utilisé GLM pour vec3 - point - cross - sub. . .

bool intersect_triangle(vec3 &O, vec3& D, vec3 &vert0, vec3 &vert1, vec3 &vert2, vec3 & P, bool cull) 
{ 
    static const float eps = 0.000001; 
    vec3 edge1(0.0f, 0.0f, 0.0f); 
    vec3 edge2(0.0f, 0.0f, 0.0f); 
    vec3 tvec(0.0f, 0.0f, 0.0f); 
    vec3 pvec(0.0f, 0.0f, 0.0f); 
    vec3 qvec(0.0f, 0.0f, 0.0f); 
    float det, inv_det; 

    edge1 = vert1 - vert0; 
    edge2 = vert2 - vert0; 
    pvec = cross(D, edge2); 
    det = dot(edge1, pvec); 

    if(cull) 
    { 
     if(det < eps) 
     { 
      cout << "cull test failed" << endl; 
      return false; 
     } 

     tvec = O - vert0; 

     P.x = dot(tvec, pvec); 

     if(P.x < 0.0f || P.x > det) 
     { 
      cout << "U test failed" << endl; 
      return false; 
     } 

     qvec = cross(tvec, edge1); 
     P.y = dot(D, qvec); 

     if(P.y < 0.0f || (P.x + P.y) > det) 
     { 
      cout << "V test failed" << endl; 
      return false; 
     } 

     P.z = dot(edge2, qvec); 
     inv_det = 1.0f/det; 
     P.x *= inv_det; 
     P.y *= inv_det; 
     P.z *= inv_det; 
    } 
    else 
    { 
     if(det > - eps && det < eps) 
     { 
      return false; 
     } 

     inv_det = 1.0f/det; 
     tvec = O - vert0; 
     P.x = dot(tvec, pvec) * inv_det; 

     if(P.x < 0.0f || P.x > 1.0f) 
     { 
      return false; 
     } 

     qvec = cross(tvec, edge1); 
     P.y = dot(D, qvec) * inv_det; 

     if(P.y < 0.0f || P.x + P.y > 1.0f) 
     { 
      return false; 
     } 

     P.z = dot(edge2, qvec) * inv_det; 
    } 

    return true; 
} 

Et je m `l'aide de la mise en œuvre comme suit;

 for(size_t i = 0; i < tris.size(); i++) 
     { 
      mat4 mvp_inverse = inverse(tris[i]->_mvp); 
      vec4 origin = mvp_inverse * vec4(
           (_lastEvent.motion.x - _width/2.0f)/_width/2.0f, (_height/2.0f - _lastEvent.motion.y)/_height/2.0f, -1, 1); 
      vec4 dir = mvp_inverse * vec4(0, 0, 1, 0); 
      vec3 O = vec3(origin.x, origin.y, origin.z); 
      vec3 D = normalize(vec3(dir.x, dir.y, dir.z)); 
      vec3 P; 

      for(size_t j = 0; j < tris[i]->_indices.size(); j += 3) 
      { 
       bool intersection = intersect_triangle(O, D, 
                 tris[i]->_vertices[tris[i]->_indices[j]], 
                 tris[i]->_vertices[tris[i]->_indices[j + 1]], 
                 tris[i]->_vertices[tris[i]->_indices[j + 2]], 
                 P, true); 

       if(intersection) 
       { 
        cout << P.x << " " << P.y << " " << P.z << endl; 
       } 
       else 
       { 
        cout << "no intersection" << endl; 
       } 
      } 
     } 

La mise en œuvre fonctionne à certains endroits. Il détecte correctement lorsque le curseur pointe à l'intérieur de tri. Cela ne fonctionne pas dans certains endroits où en dehors de tri. Je ne sais pas pourquoi? J'ai utilisé le papier "Fast, Minimum Storage Ray/Triangle Intersection" à implémenter.

Test Screenshoots;

screenshoot 1: Screenshoot 1

screenshoot 2 Screenshoot 2

+0

Ne détecte-t-il pas correctement que sur les bords ou les coins, ou ailleurs? – legends2k

+0

ailleurs ... généralement à droite du tri. regarde le screenhoot 1 pour le côté droit. –

+1

Il y a certaines choses que vous devez savoir avant d'implémenter un algorithme de test d'intersection. Il y a des fondamentaux pour la programmation graphique 3D. Les points sont-ils alimentés dans un ordre cindy ou ccwise? Si oui, où serait la direction vers laquelle pointe le vecteur normal? Quelle est votre système de coordonnées? Les chiffres que vous obtenez d'un produit croisé dépend de cela. Plus spécifiquement, avoir une compréhension mathématique/intuitive de cet algorithme et ensuite l'implémenter, il serait facile de déboguer. Sans cela, nous ne serions pas en mesure de vous aider; par exemple, que signifient les variables «D», «O», «P»? – legends2k

Répondre

0

Le problème est la construction d'origine de rayons et direction

Solution:

  vec4 viewport(0.0f, 0.0f, 800.0f, 600.0f); 

      vec3 unProjectedNear = unProject(vec3(_lastEvent.motion.x, 600 - _lastEvent.motion.y, -1.0f), _view * tris[i]->_model, _proj, viewport); 
      vec3 unProjectedFar = unProject(vec3(_lastEvent.motion.x, 600 - _lastEvent.motion.y, +1.0f), _view * tris[i]->_model, _proj, viewport); 
      vec3 D = normalize(unProjectedFar-unProjectedNear); 
      vec3 O = unProjectedNear;