0

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

这是我的功能:

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;

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

我确信我的 box vs frustum 代码是正确的。有人看到我的计算代码有错误,或者知道我确实需要转换绑定框顶点吗?

谢谢你。

4

2 回答 2

1

如果您的边界框位于世界坐标中,则应该将 viewMatrix 传递给 calculateFrustum。

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

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

于 2012-08-03T07:25:02.490 回答
0

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

这是更正方法的第一行:

m_Frustum[LEFT][A] = (*mat)[0][3] + (*mat)[0][0];
于 2016-02-10T00:05:39.083 回答