2012-02-23 5 views
9

레이 캐스팅 알고리즘에서 마우스 히트를 탐지하는 데 부정확 한 문제가 발생했습니다. 이 문제를 올바르게 해결하는 방법에 관해서는 완전히 손해를보고 있으며, 몇 주 동안 나를 괴롭 히고 있습니다. 레이 캐스팅으로 오브젝트 피킹

screen shot of problem

검은 선

그리는 실제 hitbox에서를 표현하고, 녹색 상자 나타냄

문제가 쉬운 (박스 중심 [0, 0, -30]) 사진 설명한다 실제로 맞은 것 같습니다. 오프셋이 어떻게 표시되는지 (상자가 원점에서 멀어지면 더 커지는 것처럼 보임) 그리는 히트 박스보다 약간 작습니다.

여기에 몇 가지 관련 코드입니다,

레이 박스 캐스트 : 나는 같은 실제 선을 그리는 시도했습니다

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; 
} 

:

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; 
} 

마우스 선에 선이 그려진 상자와 올바르게 교차하는 것 같습니다.

모든 점과 광선 원점/방향을 상자 위치로 빼내어 오프셋 문제가 부분적으로 해결되었지만 왜 그 점이 효과가 있었고, 적중 상자의 크기가 여전히 부정확하게 남아 있는지 알 수 없습니다.

어떤 아이디어/대안적인 접근 방법이 있습니까? 필요한 경우 다른 코드를 제공해야합니다.

답변

10

잘못된 방향을 가정합니다. 올바른 값은 다음과 같습니다.

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

근처 및 먼 교차점을 빼지 않으면 방향이 해제됩니다.

+0

감사합니다. 이것은 정확히 그것을, 대단히 감사했다 :) – sler