0

I am trying to calculate my frustum to do some simple bounding box tests.

Here is my function:

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);
}

Now before anyone tells me that I have the wrong order for the column/row, I have tried them both with no luck.

I switched over from the fixed function mode of getting my matrices like this:

glGetFloatv( GL_PROJECTION_MATRIX, proj );

glGetFloatv( GL_MODELVIEW_MATRIX, modl );

To actually passing in a matrix. The only thing I am rendering at this point is world vertices and I suspect the problem is that my bounding box locations are not taking into account the offset of where I am in the world due.

Here is my matrix creation:

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

Because the only thing I am rendering now is global vertices with absolute positions, I don't use a model matrix for anything.

I am sure my box vs frustum code is correct. Does anyone see an error with my calculation code or know that I do in fact need to transform my binding box vertices?

Thank you.

Pladnius Brooks
  • 1,248
  • 3
  • 19
  • 36

2 Answers2

1

If you have your bounding box in world coordinates than you should pass your viewMatrix to calculateFrustum.

Passing the viewMatrix to calculateFrustum will generate the planes in world space.

If you pass the projectionMatrix instead to calculateFrustum than you will have to apply the cameraMatrix to the bounding-box before performing the intersection test.

brano
  • 2,822
  • 19
  • 15
  • So, just so we are clear on terminology, my view matrix is both the camera translation, rotation and the projection matrix combined. I have passed that and still, I seem to be getting the errors. It seems that no matter what matrix I pass it, it doesn't analyze the bounding box in world space. – Pladnius Brooks Aug 03 '12 at 07:31
  • Yew we do agree on the terminology. According to the paper i posted to you in a previous post it says like this: "If the matrix is equal to the combined projection and modelview matrices, then the algorithm gives the clipping planes in model space (i.e., V*P=M, where V is the modelview matrix, and P is the projection matrix)." In your case the M is the viewMatrix and it should work. – brano Aug 03 '12 at 07:35
  • Okay. Thank you. I will keep at it. – Pladnius Brooks Aug 03 '12 at 07:39
0

I have been trying to do the same thing, tried to use this code and found the problem. It is the usual pointer confusion.

This is the first line of the method corrected:

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