2013-07-24 29 views
1

我的射線拾取代碼有問題。我的代碼OpenGL拾取 - Ray /球體交叉錯誤

我使用這個代碼採摘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; 
} 

問題是,我的代碼工作不正確。如果我直觀地使用我的球體,並在球體內部點擊,我只能得到球體一半的正確答案。當我移動相機時,比起它的全部搞砸和挑選反應在球體外面。 我的世界沒有改變(所有的世界矩陣都是身份)。只有相機正在移動。我正確地計算鼠標在OpenGL窗口中的位置(左上角有[0,0]並轉到[寬度,高度])。

PS:我在DirectX中成功使用此代碼進行光線投射/光線跟蹤。我看不出有什麼問題。我的OpenGL渲染是使用左手系統(它不是天然的OpenGL,但我想用那種方式)

編輯: 可視化射線後,問題apearing,當我MOV cameraleft /右。射線的中心與鼠標位置不是一致的。

+2

嘗試渲染挑射線?也許它會幫助你找出這是射線/球形交叉點的問題,還是計算射線本身 –

+0

我的「引擎」無法渲染線條:( –

+0

@MartinPerry它可以繪製一個非常細長的盒子/柱面如果是這樣渲染的話! –

回答

3

確定..發現別人的問題......,誰可能是interessted

於WO線是不正確的

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();