2012-08-03 65 views
0

我想計算我的平截體體來做一些簡單的邊界框測試。OpenGL/GLM - 計算平截頭體問題

這裏是我的功能:

void CFrustum::calculateFrustum(glm::mat4* mat) 
{ 
    // Calculate the LEFT side 
    m_Frustum[LEFT][A] = *glm::value_ptr(mat[0][3]) + *glm::value_ptr(mat[0][0]); 
    m_Frustum[LEFT][B] = *glm::value_ptr(mat[1][3]) + *glm::value_ptr(mat[1][0]); 
    m_Frustum[LEFT][C] = *glm::value_ptr(mat[2][3]) + *glm::value_ptr(mat[2][0]); 
    m_Frustum[LEFT][D] = *glm::value_ptr(mat[3][3]) + *glm::value_ptr(mat[3][0]); 

    // Calculate the RIGHT side 
    m_Frustum[RIGHT][A] = *glm::value_ptr(mat[0][3]) - *glm::value_ptr(mat[0][0]); 
    m_Frustum[RIGHT][B] = *glm::value_ptr(mat[1][3]) - *glm::value_ptr(mat[1][0]); 
    m_Frustum[RIGHT][C] = *glm::value_ptr(mat[2][3]) - *glm::value_ptr(mat[2][0]); 
    m_Frustum[RIGHT][D] = *glm::value_ptr(mat[3][3]) - *glm::value_ptr(mat[3][0]); 

    // Calculate the TOP side 
    m_Frustum[TOP][A] = *glm::value_ptr(mat[0][3]) - *glm::value_ptr(mat[0][1]); 
    m_Frustum[TOP][B] = *glm::value_ptr(mat[1][3]) - *glm::value_ptr(mat[1][1]); 
    m_Frustum[TOP][C] = *glm::value_ptr(mat[2][3]) - *glm::value_ptr(mat[2][1]); 
    m_Frustum[TOP][D] = *glm::value_ptr(mat[3][3]) - *glm::value_ptr(mat[3][1]); 

    // Calculate the BOTTOM side 
    m_Frustum[BOTTOM][A] = *glm::value_ptr(mat[0][3]) + *glm::value_ptr(mat[0][1]); 
    m_Frustum[BOTTOM][B] = *glm::value_ptr(mat[1][3]) + *glm::value_ptr(mat[1][1]); 
    m_Frustum[BOTTOM][C] = *glm::value_ptr(mat[2][3]) + *glm::value_ptr(mat[2][1]); 
    m_Frustum[BOTTOM][D] = *glm::value_ptr(mat[3][3]) + *glm::value_ptr(mat[3][1]); 

    // Calculate the FRONT side 
    m_Frustum[FRONT][A] = *glm::value_ptr(mat[0][3]) + *glm::value_ptr(mat[0][2]); 
    m_Frustum[FRONT][B] = *glm::value_ptr(mat[1][3]) + *glm::value_ptr(mat[1][2]); 
    m_Frustum[FRONT][C] = *glm::value_ptr(mat[2][3]) + *glm::value_ptr(mat[2][2]); 
    m_Frustum[FRONT][D] = *glm::value_ptr(mat[3][3]) + *glm::value_ptr(mat[3][2]); 

    // Calculate the BACK side 
    m_Frustum[BACK][A] = *glm::value_ptr(mat[0][3]) - *glm::value_ptr(mat[0][2]); 
    m_Frustum[BACK][B] = *glm::value_ptr(mat[1][3]) - *glm::value_ptr(mat[1][2]); 
    m_Frustum[BACK][C] = *glm::value_ptr(mat[2][3]) - *glm::value_ptr(mat[2][2]); 
    m_Frustum[BACK][D] = *glm::value_ptr(mat[3][3]) - *glm::value_ptr(mat[3][2]); 

    // Normalize all the sides 
    NormalizePlane(m_Frustum, LEFT); 
    NormalizePlane(m_Frustum, RIGHT); 
    NormalizePlane(m_Frustum, TOP); 
    NormalizePlane(m_Frustum, BOTTOM); 
    NormalizePlane(m_Frustum, FRONT); 
    NormalizePlane(m_Frustum, BACK); 
} 

現在有人告訴我,我有錯誤的順序爲列/行之前,我曾嘗試他們倆沒有運氣。

從我讓我的矩陣這樣的固定功能模式切換:

glGetFloatv(GL_PROJECTION_MATRIX, proj); 

glGetFloatv(GL_MODELVIEW_MATRIX, modl); 

要實際傳遞一個矩陣。我在這一點上渲染的唯一東西是世界頂點,我懷疑問題是我的邊界框位置沒有考慮到我在世界上應有的位置的偏移量。

這裏是我的矩陣構建:

cameraMatrix = glm::lookAt(position, position+direction, up); 
projectionMatrix = glm::perspective(50.0f, 4.0f/3.0f, 0.1f, 1000.f); 
viewMatrix = projectionMatrix * cameraMatrix; 

因爲我現在呈現的唯一的事情是絕對位置的全球頂點,我不使用一個模型矩陣的任何東西。

我確定我的盒子和平截頭體的代碼是正確的。有沒有人看到我的計算代碼錯誤或知道我確實需要變換我的綁定框頂點?

謝謝。

回答

1

如果您在世界座標中包含邊界框,則應該將您的viewMatrix傳遞給calculateFrustum。

傳遞viewMatrix來計算Fustustum將在世界空間中生成平面。

如果您通過projectionMatrix來計算Frustum,那麼在執行相交測試之前,您必須將cameraMatrix應用到邊界框。

+0

所以,只是讓我們在術語清楚,我的觀點矩陣是在相機平移,旋轉和投影矩陣相結合。我已經通過了,仍然是,我似乎得到了錯誤。似乎無論我通過哪個矩陣,它都不會分析世界空間中的邊界框。 – 2012-08-03 07:31:12

+0

我們同意這個術語。根據我在前一篇文章中給你發表的文章,它是這樣說的:「如果矩陣等於組合投影和模型視矩陣,那麼該算法給出模型空間中的剪裁平面(即V * P = M ,其中V是模型視圖矩陣,並且P是投影矩陣)。「在你的情況下,M是viewMatrix,它應該工作。 – brano 2012-08-03 07:35:24

+0

好的。謝謝。我會堅持下去。 – 2012-08-03 07:39:21

0

我一直在試圖做同樣的事情,試圖使用這段代碼,發現問題。這是通常的指針混淆。

這是該方法的第一行糾正:

m_Frustum[LEFT][A] = (*mat)[0][3] + (*mat)[0][0];