Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top