OpenGL / GLM - 计算平截头体问题

时间:2012-08-03 05:26:54

标签: c++ math opengl frustum

我正在尝试计算我的截头体来做一些简单的边界框测试。

这是我的功能:

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;

因为我现在唯一呈现的是具有绝对位置的全局顶点,所以我不会使用模型矩阵。

我确信我的盒子与视锥体代码是正确的。有没有人看到我的计算代码出错或知道我确实需要转换我的绑定框顶点?

谢谢。

2 个答案:

答案 0 :(得分:1)

如果你的世界坐标中的边界框比你应该将viewMatrix传递给calculateFrustum。

将viewMatrix传递给calculateFrustum将在世界空间中生成平面。

如果您将projectionMatrix传递给calculateFrustum,则必须在执行相交测试之前将cameraMatrix应用于边界框。

答案 1 :(得分:0)

我一直在尝试做同样的事情,尝试使用此代码并发现问题。这是通常的指针混乱。

这是纠正方法的第一行:

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