# Frustum culling - error evaluating a point in the plane of the frustum

I am trying to implement the following code:

http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-implementation/

I need to use frustum culling in my graphics engine.

my functions are:

void frustum::updateCameraData()
{
float _ratio = float(globalData::windowWidth/globalData::windowHeight);
// store the information
this->ratio = _ratio;
this->angle = globalData::cameraAngle;
this->nearD = globalData::zNear;
this->farD = globalData::zFar;

// compute width and height of the near and far m_frustumane sections
tang = (float)tan(PI * globalData::cameraAngle * 0.5) ;
nh = nearD * tang;
nw = nh * _ratio;
fh = farD  * tang;
fw = fh * _ratio;

}

void frustum::extractFrustum(vector3f camPosition, vector3f camDirection, vector3f camUp)
{
cout << "camPosition = ";
camPosition.print();
cout << " camDirection = ";
camDirection.print();
cout << " camUp = ";
camUp.print();
cout << "\n";
vector3f dir,nc,fc,X,Y,Z,Zn;

// compute the Z axis of camera
// this axis points in the opposite direction from
// the looking direction
Z = camPosition - camDirection;
Z.Normalize();

// X axis of camera with given "up" vector and Z axis
X = camUp * Z;
X.Normalize();

// the real "up" vector is the cross product of Z and X
Y = Z * X;

// compute the centers of the near and far planes
nc = camPosition - Z * nearD;
fc = camPosition - Z * farD;

// compute the 4 corners of the frustum on the near plane
ntl = nc + Y * nh - X * nw;
ntr = nc + Y * nh + X * nw;
nbl = nc - Y * nh - X * nw;
nbr = nc - Y * nh + X * nw;

// compute the 4 corners of the frustum on the far plane
ftl = fc + Y * fh - X * fw;
ftr = fc + Y * fh + X * fw;
fbl = fc - Y * fh - X * fw;
fbr = fc - Y * fh + X * fw;

Zn = vector3f(-Z.x,-Z.y,-Z.z);
m_frustum[NEARP].setNormalAndPoint(Zn,nc);
m_frustum[FARP].setNormalAndPoint(Z,fc);

vector3f aux,normal;

aux = (nc + Y*nh) - camPosition;
aux.Normalize();
normal = aux * X;
Zn = nc+Y*nh;
m_frustum[TOP].setNormalAndPoint(normal,Zn);

aux = (nc - Y*nh) - camPosition;
aux.Normalize();
normal = X * aux;

Zn = nc-Y*nh;
m_frustum[BOTTOM].setNormalAndPoint(normal,Zn);

aux = (nc - X*nw) - camPosition;
aux.Normalize();
normal = aux * Y;

Zn = nc-X*nw;
m_frustum[LEFT].setNormalAndPoint(normal,Zn);

aux = (nc + X*nw) - camPosition;
aux.Normalize();
normal = Y * aux;

Zn = nc+X*nw;
m_frustum[RIGHT].setNormalAndPoint(normal,Zn);

}

bool frustum::pointInFrustum( float x, float y, float z )
{
vector3f point = vector3f(x,y,z);

for(int i=0; i < 6; i++)
{
cout << "m_frustum[i].distance(point) = "<< m_frustum[i].distance(point) <<" < 0\n";
if (m_frustum[i].distance(point) < 0)
{
return false;
}
}
return true;
}

/*this is used to calculate the distance of point to plane*/

float distance(vector3f &p) {

return (d + normal.innerProduct(p));
}


however, I get unwanted results (this are my debug messages):

   camPosition = (0, 15, 40) camDirection = (0, 0, 0) camUp = (0, 1, 0)

NO DRAWN: object0
posicion: -20,0,-20
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(-20,0,-20)
m_frustum[3].distance(point) = -15.0501 < 0
NO DRAWN: object1
posicion: 0,0,-20
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(0,0,-20)
m_frustum[3].distance(point) = -15.0501 < 0
NO DRAWN: object2
posicion: 20,0,-7
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(20,0,-7)
m_frustum[3].distance(point) = -15.0501 < 0
NO DRAWN: object3
posicion: -40,0,-20
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[0].distance(point) = 14.7867 < 0
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[1].distance(point) = 14.485 < 0
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[2].distance(point) = 14.2216 < 0
/*object position*/ vector3f point = vector3f(-40,0,-20)
m_frustum[3].distance(point) = -15.0501 < 0


None of the objects passed the test (I test with pointInFrustrum(), using the point as position of each object.

if I render the scene without frustum culling, everything looks perfect, but to use it, nothing passes the test. any idea where can be the error? (the code is that the link which I have mentioned above).

All objects are with in visual field...

The matrix is managed with glm::mat4;

EDIT:

After I have made the corrections mentioned by "Ello", if I point the camera a bit downward, the objects are drawn, but if I point the camera a bit up, all the objects disappear completely (They are not drawn this time). Do you know what may be happening? Thanks in advance.

if the camera points downward:

if the camera points a bit up:

• You set the near and far planes using Zn, nc, Z & fc. As far as I can tell only Zn is initialized. Maybe your problem is here? – GuyRT Aug 5 '14 at 9:41
• Thanks GuyRT, (after much testing) i forgot that mistake, anyway, I fix it but the problem persists .. really can not find the reason why not draw any object on screen. i update the post whit the complete code. Of course I appreciate your help – user2303826 Aug 5 '14 at 22:51
• I once had a similar error. For my problem, an errornous vector normalize method was the source. I corrected the wrong normalize() implementation and fixed my error. This is just a comment, no solution. Maybe this can help you. – Ello Aug 6 '14 at 14:33
• another thing, which is "suspicios", is that on your output, the distances are always the same, even if the initial point changes. I guess this is false. Maybe some mistakes at distance checking? – Ello Aug 6 '14 at 15:15
• Thanks Ello, I've updated the post with new data received (DEBUG DATA) and some pictures to show the problem. I hope your help, thanks! – user2303826 Aug 6 '14 at 23:27