2012-08-03 98 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];