【问题标题】:OpenGL/GLM - Calculating frustum problemsOpenGL/GLM - 计算平截头体问题
【发布时间】:2023-03-17 04:00:02
【问题描述】:

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

这是我的功能:

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 代码是正确的。是否有人看到我的计算代码有错误或知道我确实需要转换绑定框顶点?

谢谢。

【问题讨论】:

    标签: c++ math opengl frustum


    【解决方案1】:

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

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

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

    【讨论】:

    • 所以,只要我们清楚术语,我的视图矩阵就是相机平移、旋转和投影矩阵的组合。我已经通过了,但我似乎得到了错误。好像不管我传什么矩阵,它都不分析世界空间中的边界框。
    • 是的,我们确实同意术语。根据我在上一篇文章中发布给您的论文,它是这样说的:“如果矩阵等于组合投影和模型视图矩阵,那么算法给出模型空间中的裁剪平面(即 V*P=M,其中 V 是模型视图矩阵,P 是投影矩阵)。”在您的情况下,M 是 viewMatrix,它应该可以工作。
    • 好的。谢谢你。我会坚持下去的。
    【解决方案2】:

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

    这是改正方法的第一行:

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

    【讨论】:

      猜你喜欢
      • 2013-01-18
      • 1970-01-01
      • 2019-05-12
      • 2018-02-28
      • 2021-05-25
      • 1970-01-01
      • 2011-09-11
      • 2015-01-31
      • 1970-01-01
      相关资源
      最近更新 更多