Help those suffering in the Horn of Africa

Clip Space Approach – Implementation Details

Prev: Clip Space Approach - Extracting the Planes Next: Radar Approach - Testing Points
 

The following function, from class FrustumG, performs the plane extraction as described above, assuming that the matriz A=M*P is given as a parameter:

#define m(row,col)  m[col*4+row-5]

void FrustumG::setFrustum(float *m) {

	pl[NEARP].setCoefficients(
				 m(3,1) + m(4,1),
				 m(3,2) + m(4,2),
				 m(3,3) + m(4,3),
				 m(3,4) + m(4,4));
	pl[FARP].setCoefficients(
				-m(3,1) + m(4,1),
				-m(3,2) + m(4,2),
				-m(3,3) + m(4,3),
				-m(3,4) + m(4,4));
	pl[BOTTOM].setCoefficients(
				 m(2,1) + m(4,1),
				 m(2,2) + m(4,2),
				 m(2,3) + m(4,3),
				 m(2,4) + m(4,4));
	pl[TOP].setCoefficients(
				-m(2,1) + m(4,1),
				-m(2,2) + m(4,2),
				-m(2,3) + m(4,3),
				-m(2,4) + m(4,4));
	pl[LEFT].setCoefficients(
				 m(1,1) + m(4,1),
				 m(1,2) + m(4,2),
				 m(1,3) + m(4,3),
				 m(1,4) + m(4,4));
	pl[RIGHT].setCoefficients(
				-m(1,1) + m(4,1),
				-m(1,2) + m(4,2),
				-m(1,3) + m(4,3),
				-m(1,4) + m(4,4));
}

#undef M

The function setCoefficients from the class Plane is as follows:

void Plane::setCoefficients(float a, float b, float c, float d) {

	// set the normal vector
	normal.set(a,b,c);
	//compute the lenght of the vector
	float l = normal.length();
	// normalize the vector
	normal.set(a/l,b/l,c/l);
	// and divide d by th length as well
	this->d = d/l;
}

To extract the matrices M and P from OpenGL state the function glGetFloatv can be used:

	float m[16],p[16];

	glGetFloatv(GL_PROJECTION_MATRIX,p);
	glGetFloatv(GL_MODELVIEW_MATRIX,m);

Matrix multiplication is then performed to compute A = M*P. A simple matrix multiplication such as the one below will do:

void multMat(float *res,float *a, float *b) {

	for (int i=0;i<4;i++) {
		for (int j = 0;j < 4;j++) {
			res[i*4+j] = 0.0;
			for (int k = 0; k < 4; k++) {
				res[i*4+j] += a[i*4+k] * b[k*4+j];
			}
		}
	}
}

The following is a solution for lazy people, using OpenGL to perform the multiplication for you (in my laptop it is actually slightly faster!) :

void multMat2(float *res, float *a, float *b) {

	glPushMatrix();

	glLoadMatrixf(b);
	glMultMatrixf(a);
	glGetFloatv(GL_MODELVIEW_MATRIX, res);

	glPopMatrix();
}

Once the planes are extracted, testing points, spheres or boxes, works exactly as in the geometric approach.

 

Prev: Clip Space Approach - Extracting the Planes Next: Radar Approach - Testing Points
 

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2012 Lighthouse3d.com Suffusion theme by Sayontan Sinha