2012-02-23 101 views
9

我一直在使用我的光線投射算法檢測盒子內的鼠標點擊時出現不準確的問題。對於如何正確解決這個問題,我完全不知所措,而且幾周來一直困擾着我。使用光線投射物體拾取

問題是最容易與圖片描述(框圍繞着[0,0,-30):

screen shot of problem

黑線表示其被繪製的實際擊中格和綠色框表示實際上似乎受到打擊。注意它是如何偏移的(如果框距離原點越遠似乎越大)並略小於繪製的hitbox。

下面是一些相關的代碼,

射線箱投:

double BBox::checkFaceIntersection(Vector3 points[4], Vector3 normal, Ray3 ray) { 

    double rayDotNorm = ray.direction.dot(normal); 
    if(rayDotNorm == 0) return -1; 

    Vector3 intersect = points[0] - ray.origin; 
    double t = intersect.dot(normal)/rayDotNorm; 
    if(t < 0) return -1; 

    // Check if first point is from under or below polygon 
    bool positive = false; 
    double firstPtDot = ray.direction.dot((ray.origin - points[0]).cross(ray.origin - points[1])); 
    if(firstPtDot > 0) positive = true; 
    else if(firstPtDot < 0) positive = false; 
    else return -1; 

    // Check all signs are the same 
    for(int i = 1; i < 4; i++) { 
     int nextPoint = (i+1) % 4; 
     double rayDotPt = ray.direction.dot((ray.origin - points[i]).cross(ray.origin - points[nextPoint])); 
     if(positive && rayDotPt < 0) { 
      return -1; 
     } 
     else if(!positive && rayDotPt > 0) { 
      return -1; 
     } 
    } 

    return t; 
} 

鼠標線:

GLint viewport[4]; 
GLdouble modelMatrix[16]; 
GLdouble projectionMatrix[16]; 

glGetIntegerv(GL_VIEWPORT, viewport); 
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); 
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); 

GLfloat winY = GLfloat(viewport[3] - mouse_y); 

Ray3 ray; 
double x, y, z; 
gluUnProject((double) mouse_x, winY, 0.0f, // Near 
       modelMatrix, projectionMatrix, viewport, 
       &x, &y, &z); 
ray.origin = Vector3(x, y, z); 

gluUnProject((double) mouse_x, winY, 1.0f, // Far 
       modelMatrix, projectionMatrix, viewport, 
      &x, &y, &z); 
ray.direction = Vector3(x, y, z); 

if(bbox.checkBoxIntersection(ray) != -1) { 
    std::cout << "Hit!" << std::endl; 
} 

我試着繪製的實際光線的線,它似乎正確地交叉繪製框。

我的偏移問題部分地通過縮小所有點和射線的原點/方向的位置來固定,但我不知道爲什麼這種方法奏效,hitbox的大小仍然不準確。

任何想法/替代方法?如果需要,我還提供其他代碼。

回答

10

你正在假設一個錯誤的方向。正確的將是:

ray.direction = Vector3(far.x - near.x, far.y - near.y, far.z - near.z); 

不減去近和遠交點,你的方向將被關閉。

+0

謝謝!這就是它,非常感謝:) – sler 2012-02-23 11:00:24