2013-07-24 2 views
1

레이 피킹 코드에 문제가 있습니다. 내 코드OpenGL 피킹 - 레이/구 교차가 잘못되었습니다.

내가 따기 calulation이 코드를 사용하고 있습니다 :

/*----------------------------------------------------------- 
Function: GetViewportSystem 
Returns: 
    viewportCoordSystem 

Get viewport coordinate system (only for reading) 
Forward ray goes through origin 
-------------------------------------------------------------*/ 
ViewportCoordSystem Camera::GetViewportSystem() const 
{ 
    ViewportCoordSystem viewportCoord; 
    viewportCoord.w = this->cameraPos; 
    viewportCoord.w -= this->lookAt; 
    viewportCoord.w.Normalize(); 

    viewportCoord.u = MyMath::Vector3::Cross(MyMath::Vector3::UnitY(), viewportCoord.w); 

    viewportCoord.v = MyMath::Vector3::Cross(viewportCoord.w, viewportCoord.u); 

    float d = (this->viewport.Height/2.0f) * (1.0f/tanf(this->viewport.fov/2.0f)); 
    viewportCoord.origin = this->cameraPos; 
    viewportCoord.origin -= d * viewportCoord.w; 

    return viewportCoord; 
} 

/*----------------------------------------------------------- 
Function: MapViewport2Dto3D 
Parametrs: 
    [in] viewportSystem - cameras viewport coordinate system 
    [in] point - 2D point on image 
Returns: 
    3D mapped point in space 

Map 2D image point to 3D space 
Info about mapping 2D to 3D: http://meatfighter.com/juggler/ 
-------------------------------------------------------------*/ 
MyMath::Vector3 Camera::MapViewport2Dto3D(const ViewportCoordSystem & viewportSystem, const MyMath::Vector2 & point) const 
{ 
    MyMath::Vector3 res = viewportSystem.origin; 
    res += (point.X - this->viewport.Width * 0.5f) * viewportSystem.u; 
    res += (this->viewport.Height * 0.5f - point.Y) * viewportSystem.v; 
    return res; 
} 

이 선으로 자체

ViewportCoordSystem vpSystem = this->camera->GetViewportSystem(); 
MyMath::Vector3 pos = this->camera->MapViewport2Dto3D(vpSystem, MyMath::Vector2(mouseX, mouseY)); 

this->ray.dir = pos - this->camera->GetPosition(); 
this->ray.dir.Normalize(); 

this->ray.origin = this->camera->GetPosition(); 

따기, 나는 선을 계산 - 구 교차 시험.

bool BoundingSphere::RayIntersection(const MyMath::Ray & ray) const 
{ 
    MyMath::Vector3 Q = this->sphereCenter - ray.origin; 
    double c = Q.LengthSquared(); 
    double v = MyMath::Vector3::Dot(Q, ray.dir); 
    double d = this->sphereRadius * this->sphereRadius - (c - v * v); 

    if (d < 0.0) return false; 

    return true; 
} 

문제는 내 코드가 잘못 작동한다. 내 구체를 시각화하고 그 내부를 클릭하면 구체의 절반 만 올바른 답을 얻었습니다. 내가 카메라를 움직일 때, 모든 것이 엉망이되어 피킹이 구체 밖에서 반응합니다. 내 세계가 변형되지 않았습니다 (모든 세계 행렬은 ID입니다). 카메라 만 움직이고 있습니다. OpenGL 윈도우 내에서 마우스 위치를 올바르게 계산합니다 (왼쪽 위 모서리는 [0, 0]이고 [너비, 높이]로 이동).

추신 : 나는이 코드를 DirectX에서 raycasting/raytracing 용으로 사용하고 있습니다. 그리고 나는 그것으로 잘못된 것을 볼 수 없습니다. 내 OpenGL은 렌더링은 왼쪽 손으로 시스템 사용 (OpenGL을위한 자연하지,하지만 난 그런 식으로 원하는)

편집 : 내가 바로/cameraleft MOV 때,이 선을 시각화 한 후, 문제가 apearing됩니다 . 광선의 중심은 마우스 위치와 일치하지 않습니다.

+2

이 선택을 렌더링하는 시도입니다 잘못된

을 interessted 수 있습니다 다른 사람에 대한 문제 ...을 발견 레이? 어쩌면 광선/구 교차점이나 광선 자체를 계산할 때 도움이 될 것입니다. –

+0

"엔진"이 줄을 렌더링 할 수 없습니다 :( –

+0

@MartinPerry 매우 얇고 긴 상자/실린더를 그릴 수 있습니까? 만약 그렇다면 그것을 렌더링하십시오! –

답변

3

좋아 .. 선 하시다 사람들은

viewportCoord.u = MyMath::Vector3::Cross(MyMath::Vector3::UnitY(), viewportCoord.w); 
viewportCoord.v = MyMath::Vector3::Cross(viewportCoord.w, viewportCoord.u); 

전문 솔루션

viewportCoord.u = MyMath::Vector3::Cross(viewportCoord.w, MyMath::Vector3::UnitY()); 
viewportCoord.u.Normalize(); 
viewportCoord.v = MyMath::Vector3::Cross(viewportCoord.u, viewportCoord.w); 
viewportCoord.v.Normalize();