Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm having problems with my frustum being in the wrong origin. It follows the rotation of my camera but not the position.

In my camera class I'm generating a view-matrix:

void Camera::Update()
{
    UpdateViewMatrix();

    glMatrixMode(GL_MODELVIEW);
    //glLoadIdentity();
    glLoadMatrixf(GetViewMatrix().m);
}

Then extracting the planes using the projection matrix and modelview matrix:

void UpdateFrustum()
{
    Matrix4x4 projection, model, clip;

    glGetFloatv(GL_PROJECTION_MATRIX, projection.m);
    glGetFloatv(GL_MODELVIEW_MATRIX, model.m);

    clip = model * projection;

    m_Planes[RIGHT][0] = clip.m[ 3] - clip.m[ 0];
    m_Planes[RIGHT][1] = clip.m[ 7] - clip.m[ 4];
    m_Planes[RIGHT][2] = clip.m[11] - clip.m[ 8];
    m_Planes[RIGHT][3] = clip.m[15] - clip.m[12];
    NormalizePlane(RIGHT);

    m_Planes[LEFT][0] = clip.m[ 3] + clip.m[ 0];
    m_Planes[LEFT][1] = clip.m[ 7] + clip.m[ 4];
    m_Planes[LEFT][2] = clip.m[11] + clip.m[ 8];
    m_Planes[LEFT][3] = clip.m[15] + clip.m[12];
    NormalizePlane(LEFT);

    m_Planes[BOTTOM][0] = clip.m[ 3] + clip.m[ 1];
    m_Planes[BOTTOM][1] = clip.m[ 7] + clip.m[ 5];
    m_Planes[BOTTOM][2] = clip.m[11] + clip.m[ 9];
    m_Planes[BOTTOM][3] = clip.m[15] + clip.m[13];
    NormalizePlane(BOTTOM);

    m_Planes[TOP][0] = clip.m[ 3] - clip.m[ 1];
    m_Planes[TOP][1] = clip.m[ 7] - clip.m[ 5];
    m_Planes[TOP][2] = clip.m[11] - clip.m[ 9];
    m_Planes[TOP][3] = clip.m[15] - clip.m[13];
    NormalizePlane(TOP);

    m_Planes[NEAR][0] = clip.m[ 3] + clip.m[ 2];
    m_Planes[NEAR][1] = clip.m[ 7] + clip.m[ 6];
    m_Planes[NEAR][2] = clip.m[11] + clip.m[10];
    m_Planes[NEAR][3] = clip.m[15] + clip.m[14];
    NormalizePlane(NEAR);

    m_Planes[FAR][0] = clip.m[ 3] - clip.m[ 2];
    m_Planes[FAR][1] = clip.m[ 7] - clip.m[ 6];
    m_Planes[FAR][2] = clip.m[11] - clip.m[10];
    m_Planes[FAR][3] = clip.m[15] - clip.m[14];
    NormalizePlane(FAR);
}

void NormalizePlane(int side)
{
    float length =  1.0/(float)sqrt(m_Planes[side][0] * m_Planes[side][0] +
                                m_Planes[side][1] * m_Planes[side][1] +
                                m_Planes[side][2] * m_Planes[side][2]);

    m_Planes[side][0] *= length;
    m_Planes[side][1] *= length;
    m_Planes[side][2] *= length;
    m_Planes[side][3] *= length;
}

And check against it with:

bool PointInFrustum(float x, float y, float z)
{
    for(int i = 0; i < 6; i++)
    {
        if( m_Planes[i][0] * x + m_Planes[i][1] * y + m_Planes[i][2] * z + m_Planes[i][3] <= 0 )
        return false;
    }
    return true;
}

Then i render using:

camera->Update();
UpdateFrustum();

int numCulled = 0;

for(int i = 0; i < (int)meshes.size(); i++)
{
    if(!PointInFrustum(meshCenter.x, meshCenter.y, meshCenter.z))
    {
        meshes[i]->SetDraw(false); 
        numCulled++;
    }
    else
        meshes[i]->SetDraw(true);
}

Matrices look like (Camera is at (5, 0, 0)):

ModelView
[0,0,0.99,0] [0,1,0,0] [-0.99,0,0,0] [0,0,-5,1] 

Projection
[0.814,0,0,0] [0,1.303,0,0] [0,0,-1,0] [0,0,-0.02,0]

Clip
[0,0,-1,-0.999] [0,1.30,0,0] [-0.814,0,0,0] [0,0,4.98,4.99]

What am I doing wrong?

share|improve this question
    
Can you output some of the matrices view,proj & clip? Just to check that they have the expected orientation... –  Aki Suihkonen Oct 30 '12 at 17:41
    
Hmm. If your camera is at x=5,y=z=0, then why does the MV matrix have -5 at the 'z' location? –  Aki Suihkonen Oct 31 '12 at 6:57
    
Hi @Xbetas - you don't need to put "SOLVED" in your title. Just make sure you mark the answer you posted as the accepted answer when you can, and your question will be marked as having an accepted answer (though still this won't appear in the title). –  Jonathan Hobbs Oct 31 '12 at 14:00

2 Answers 2

up vote 2 down vote accepted

It appeared that the points i were testing against had not been scaled, while the render code had. So it was working all along, but the change was too small to see!

share|improve this answer
  makePlane(m[3]+m[0],m[7]+m[4],m[11]+m[8],m[15]+m[12]); // left plane

  function makePlane(a,b,c,d) {
      s=1.0/Math.sqrt(a*a+b*b+c*c);
      return [a*s,b*s,c*s,d*s]
      // NOT return [a/s,b/s,c/s,d/s]  ...
  }

BTW, if you are only clipping single points, then a more efficient method is to calculate [x,y,z,1] * clip_matrix -> [X,Y,Z,W] and to check that |X|<|W|, |Y|<|W|,|Z|<|W|.

I'm justifying using 'makePlane' approach because I cull axis aligned bounding boxes and have something more in the makePlane routine that makes the frustumCulling function to choose a single corner of the boundingbox per clipping plane.

share|improve this answer
    
I have tried to do so, but the fourth value is right on the planes when i normalize the distance too. –  Xbetas Oct 30 '12 at 16:54
    
sorry for the confusion. That fragment up there is from my working application. –  Aki Suihkonen Oct 30 '12 at 17:08
    
That gives the exact same result as i had before. –  Xbetas Oct 30 '12 at 17:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.