how can I get the bottom rectanle of the frustum

The camera is moving, both direction and position are changing.
I can get the normal of the bottom plane of the frustum now. But how can I get the coordinate of the four corners of the plane. Better code pieces, I am rather new in terms of 3D. Using openGL.

Thanks in advance.

If you know how you define the projection matrix, you can compute easily compute those cordinates.
Assuming that you don’t know how, here’s a generic method :

1- get the projection matrix.
2- invert the projection matrix.
3- multiply the vertex “corners” with this inverted matrix.

So, there we go :

1- get the projection matrix :
GLfloat projection[16];
glGetFloatv(GL_PROJECTION_MATRIX, projection[16]);

2- invert the projection matrix :
GLfloat inv_projection[16];
invert(inv_projection, projection); /* use your favourite inversion method */

3- multiply the vertex “corners” with this inverted matrix.
GLfloat lower_left_near[3];
GLfloat lower_right_near[3];
GLfloat lower_left_far[3];
GLfloat lower_right_far[3];
multiply(lower_left_near, inv_projection, -1.0f, -1.0f, -1.0f, 1.0f);
multiply(lower_right_near, inv_projection, +1.0f, -1.0f, -1.0f, 1.0f);
multiply(lower_left_far, inv_projection, -1.0f, -1.0f, +1.0f, 1.0f);
multiply(lower_right_far, inv_projection, +1.0f, -1.0f, +1.0f, 1.0f);

Note that you have to get the projection matrix AFTER it has been defined, eg after calling functions like glFrustum or gluPerspective. You have to get this matrix anytime the window is resized.

I don’t define any matrix inversion method. You have to write your own “invert()” method.

the “multiply()” method should look like :
void multiply(GLfloat *vec, const GLfloat *mat, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GLfloat vec_w;
vec[0]=mat[0]*x+mat[4]*y+mat[8]*z+mat[12]*w;
vec[1]=mat[1]*x+mat[5]*y+mat[9]*z+mat[13]*w;
vec[2]=mat[2]*x+mat[6]*y+mat[10]*z+mat[14]*w;
vec_w=mat[3]*x+mat[7]*y+mat[11]*z+mat[15]*w;
vec[0]/=vec_w;
vec[1]/=vec_w;
vec[2]/=vec_w;
}

in this method, the x, y, z and w represents the homogeneous coordinates of the vertex to transform. In the projection matrix, all x, y and z coordinates are clamped to [-1,+1], eg projected coordinates lower than -1 or greater than +1 is considered of of the frustum. In fact, the frustum is defined by a cube whose coordinates lie between (-1,-1,-1) and (+1,+1,+1).

Hope this helps.

Thank a lot. But seems that I do not understand why do the inversion and how to do the inversion. I think I have a way to do so. Seems I can get all the six plans in the frustum, so that from three planes I can get a point. I will take a try.

Also, I supposed that the method retrieved coordinates for the identity modelview matrix.
In fact, you also have to invert the modelview matrix because your camera moves and/or rotates.

Well, let’s get into some explanations. No more code. (sorry )

In OpenGL, the vertex transformation sequence is :

object coordinates -> [modelview matrix] -> eye coordinates -> [projection matrix] -> clip coordinates -> (perspective division) -> normalized device coordinates -> [viewport transformation] -> window coordinates ->

Say the object coordinates is O, the modelview matrix is M, eye coordinates is E, projection matrix is P and clip coordinates is C.

Then the mathematical formula to compute clip coordinates from object coordinates is :
E = M * O
C = P * E = P * (M * O)

That’s the standard vertex transformation. But what you want to have is the object coordinates for particular corners of the clipping frustum.
Mathematically, you want to compute object coordinates O from clip coordinates C.
C = P * E => E = inv§ * C
E = M * O => O = inv(M) * E = inv(M) * (inv§ * C)

In OpenGL, clip coordinates C have four components (Xc Yc Zc Wc). Those coordinates lie in the clipping frustum if -Wc <= Xc <= +Wc, and -Wc <= Yc <= +Wc, and -Wc <= Zc <= +Wc (where ‘<=’ is the symbol ‘lower or equal’) eg clipping planes are defined for :
Xc - Wc == 0
Xc + Wc == 0
Yc - Wc == 0
Yc + Wc == 0
Zc - Wc == 0
Zc + Wc == 0

Obvisouly, the points where those planes intersect are :
(Xc Yc Zc) == (-Wc -Wc -Wc)
(Xc Yc Zc) == (-Wc -Wc +Wc)
(Xc Yc Zc) == (-Wc +Wc -Wc)
(Xc Yc Zc) == (-Wc +Wc +Wc)
(Xc Yc Zc) == (+Wc -Wc -Wc)
(Xc Yc Zc) == (+Wc -Wc +Wc)
(Xc Yc Zc) == (+Wc +Wc -Wc)
(Xc Yc Zc) == (+Wc +Wc +Wc)

These are the 8 corners of the clipping frustum in CLIP COORDINATES.

To retrieve those coordinates in object coordinates (eg in local coordinates of your 3D world), just use the above mathematical formula O = inv(M) * (inv§ * C) with the 8 values of C, where each coordinate C is defined by the quadruplet (Xc Yc Zc Wc).
Because these are homogeneous coordinates, remember that you can choose any non-nul Wc, and I recommend Wc=1.
In homogeneous clip coordinates, these 8 points become :
C == (-1, -1, -1, 1)
C == (-1, -1, +1, 1)
C == (-1, +1, -1, 1)
C == (-1, +1, +1, 1)
C == (+1, -1, -1, 1)
C == (+1, -1, +1, 1)
C == (+1, +1, -1, 1)
C == (+1, +1, +1, 1)

and you have to compute he 8 corresponding object coordinates O using the mathematical formula.

Is it clear enough ?

I’m sorry if I skipped some elemental details, but because you’re posting your question in the “OpenGL coding: advanced” forum, I assume that you have some basis of mathematics (which are quite simple for this problem, indeed).

thx!
I got it through anyway. I will have three weeks experience after this Wednesday, but I am a quick learner

Here is the some of the code:

void CFrustum::CalculateFrustum()
{
float proj[16]; // This will hold our projection matrix
float modl[16]; // This will hold our modelview matrix
float clip[16]; // This will hold the clipping planes

int i=0;
static int interval;
interval++;
// glGetFloatv() is used to extract information about our OpenGL world.
// Below, we pass in GL_PROJECTION_MATRIX to abstract our projection matrix.
// It then stores the matrix into an array of [16].
glGetFloatv( GL_PROJECTION_MATRIX, proj );

// By passing in GL_MODELVIEW_MATRIX, we can abstract our model view matrix.
// This also stores it in an array of [16].
glGetFloatv( GL_MODELVIEW_MATRIX, modl );

// Now that we have our modelview and projection matrix, if we combine these 2 matrices,
// it will give us our clipping planes.  To combine 2 matrices, we multiply them.

clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];

clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];

clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];

clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];

#if 0
if(interval%30==0)
{
for(i=0; i< 16; i++)
{
if(i%4==0)
g_out.Insert("
");
g_out.Insert("proj[%d]:%f “, i, proj[i]);
}
g_out.Insert(”
");

	for(i=0; i&lt; 16; i++)
	{
		if(i%4==0)
			g_out.Insert("

");
g_out.Insert("modl[%d]:%f “, i, modl[i]);
}
g_out.Insert(”
");

	for(i=0; i&lt; 16; i++)
	{
		if(i%4==0)
			g_out.Insert("

");
g_out.Insert("clip[%d]:%f “, i, clip[i]);
}
g_out.Insert(”

");
}
#endif

// Now we actually want to get the sides of the frustum.  To do this we take
// the clipping planes we received above and extract the sides from them.

// This will extract the RIGHT side of the frustum
m_Frustum[RIGHT][A] = clip[ 3] - clip[ 0];
m_Frustum[RIGHT][b] = clip[ 7] - clip[ 4];
m_Frustum[RIGHT][C] = clip[11] - clip[ 8];
m_Frustum[RIGHT][D] = clip[15] - clip[12];

// Now that we have a normal (A,B,C) and a distance (D) to the plane,
// we want to normalize that normal and distance.

// Normalize the RIGHT side
NormalizePlane(m_Frustum, RIGHT);

// This will extract the LEFT side of the frustum
m_Frustum[LEFT][A] = clip[ 3] + clip[ 0];
m_Frustum[LEFT][b] = clip[ 7] + clip[ 4];
m_Frustum[LEFT][C] = clip[11] + clip[ 8];
m_Frustum[LEFT][D] = clip[15] + clip[12];

// Normalize the LEFT side
NormalizePlane(m_Frustum, LEFT);

// This will extract the BOTTOM side of the frustum
m_Frustum[BOTTOM][A] = clip[ 3] + clip[ 1];
m_Frustum[BOTTOM][b] = clip[ 7] + clip[ 5];
m_Frustum[BOTTOM][C] = clip[11] + clip[ 9];
m_Frustum[BOTTOM][D] = clip[15] + clip[13];

// Normalize the BOTTOM side
NormalizePlane(m_Frustum, BOTTOM);

// This will extract the TOP side of the frustum
m_Frustum[TOP][A] = clip[ 3] - clip[ 1];
m_Frustum[TOP][b] = clip[ 7] - clip[ 5];
m_Frustum[TOP][C] = clip[11] - clip[ 9];
m_Frustum[TOP][D] = clip[15] - clip[13];


// Normalize the TOP side
NormalizePlane(m_Frustum, TOP);

// This will extract the BACK side of the frustum
m_Frustum[BACK][A] = clip[ 3] - clip[ 2];
m_Frustum[BACK][b] = clip[ 7] - clip[ 6];
m_Frustum[BACK][C] = clip[11] - clip[10];
m_Frustum[BACK][D] = clip[15] - clip[14];

// Normalize the BACK side
NormalizePlane(m_Frustum, BACK);

// This will extract the FRONT side of the frustum
m_Frustum[FRONT][A] = clip[ 3] + clip[ 2];
m_Frustum[FRONT][b] = clip[ 7] + clip[ 6];
m_Frustum[FRONT][C] = clip[11] + clip[10];
m_Frustum[FRONT][D] = clip[15] + clip[14];

void CFrustum::CalculateFrustum()
{
float proj[16]; // This will hold our projection matrix
float modl[16]; // This will hold our modelview matrix
float clip[16]; // This will hold the clipping planes

int i=0;
static int interval;
interval++;
// glGetFloatv() is used to extract information about our OpenGL world.
// Below, we pass in GL_PROJECTION_MATRIX to abstract our projection matrix.
// It then stores the matrix into an array of [16].
glGetFloatv( GL_PROJECTION_MATRIX, proj );

// By passing in GL_MODELVIEW_MATRIX, we can abstract our model view matrix.
// This also stores it in an array of [16].
glGetFloatv( GL_MODELVIEW_MATRIX, modl );

// Now that we have our modelview and projection matrix, if we combine these 2 matrices,
// it will give us our clipping planes.  To combine 2 matrices, we multiply them.

clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];

clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];

clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];

clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];

#if 0
if(interval%30==0)
{
for(i=0; i< 16; i++)
{
if(i%4==0)
g_out.Insert("
");
g_out.Insert("proj[%d]:%f “, i, proj[i]);
}
g_out.Insert(”
");

	for(i=0; i&lt; 16; i++)
	{
		if(i%4==0)
			g_out.Insert("

");
g_out.Insert("modl[%d]:%f “, i, modl[i]);
}
g_out.Insert(”
");

	for(i=0; i&lt; 16; i++)
	{
		if(i%4==0)
			g_out.Insert("

");
g_out.Insert("clip[%d]:%f “, i, clip[i]);
}
g_out.Insert(”

");
}
#endif

// Now we actually want to get the sides of the frustum.  To do this we take
// the clipping planes we received above and extract the sides from them.

// This will extract the RIGHT side of the frustum
m_Frustum[RIGHT][A] = clip[ 3] - clip[ 0];
m_Frustum[RIGHT][b] = clip[ 7] - clip[ 4];
m_Frustum[RIGHT][C] = clip[11] - clip[ 8];
m_Frustum[RIGHT][D] = clip[15] - clip[12];

// Now that we have a normal (A,B,C) and a distance (D) to the plane,
// we want to normalize that normal and distance.

// Normalize the RIGHT side
NormalizePlane(m_Frustum, RIGHT);

// This will extract the LEFT side of the frustum
m_Frustum[LEFT][A] = clip[ 3] + clip[ 0];
m_Frustum[LEFT][b] = clip[ 7] + clip[ 4];
m_Frustum[LEFT][C] = clip[11] + clip[ 8];
m_Frustum[LEFT][D] = clip[15] + clip[12];

// Normalize the LEFT side
NormalizePlane(m_Frustum, LEFT);

// This will extract the BOTTOM side of the frustum
m_Frustum[BOTTOM][A] = clip[ 3] + clip[ 1];
m_Frustum[BOTTOM][b] = clip[ 7] + clip[ 5];
m_Frustum[BOTTOM][C] = clip[11] + clip[ 9];
m_Frustum[BOTTOM][D] = clip[15] + clip[13];

// Normalize the BOTTOM side
NormalizePlane(m_Frustum, BOTTOM);

// This will extract the TOP side of the frustum
m_Frustum[TOP][A] = clip[ 3] - clip[ 1];
m_Frustum[TOP][b] = clip[ 7] - clip[ 5];
m_Frustum[TOP][C] = clip[11] - clip[ 9];
m_Frustum[TOP][D] = clip[15] - clip[13];


// Normalize the TOP side
NormalizePlane(m_Frustum, TOP);

// This will extract the BACK side of the frustum
m_Frustum[BACK][A] = clip[ 3] - clip[ 2];
m_Frustum[BACK][b] = clip[ 7] - clip[ 6];
m_Frustum[BACK][C] = clip[11] - clip[10];
m_Frustum[BACK][D] = clip[15] - clip[14];

// Normalize the BACK side
NormalizePlane(m_Frustum, BACK);

// This will extract the FRONT side of the frustum
m_Frustum[FRONT][A] = clip[ 3] + clip[ 2];
m_Frustum[FRONT][b] = clip[ 7] + clip[ 6];
m_Frustum[FRONT][C] = clip[11] + clip[10];
m_Frustum[FRONT][D] = clip[15] + clip[14];

// Normalize the FRONT side
NormalizePlane(m_Frustum, FRONT);

}

}

void CFrustum::caculate_corners()
{
back_lower_left.x = CMy_math::get_x_from_equation33(
m_Frustum[LEFT][A],m_Frustum[BOTTOM][A],m_Frustum[BACK][A],
m_Frustum[LEFT][b],m_Frustum[BOTTOM][b],m_Frustum[BACK][b],
m_Frustum[LEFT][C],m_Frustum[BOTTOM][C],m_Frustum[BACK][C],
-m_Frustum[LEFT][D],-m_Frustum[BOTTOM][D],-m_Frustum[BACK][D]
);
back_lower_left.y = CMy_math::get_y_from_equation33(
m_Frustum[LEFT][A],m_Frustum[BOTTOM][A],m_Frustum[BACK][A],
m_Frustum[LEFT][b],m_Frustum[BOTTOM][b],m_Frustum[BACK][b],
m_Frustum[LEFT][C],m_Frustum[BOTTOM][C],m_Frustum[BACK][C],
-m_Frustum[LEFT][D],-m_Frustum[BOTTOM][D],-m_Frustum[BACK][D]
);
back_lower_left.z = -CMy_math::get_z_from_equation33(
m_Frustum[LEFT][A],m_Frustum[BOTTOM][A],m_Frustum[BACK][A],
m_Frustum[LEFT][b],m_Frustum[BOTTOM][b],m_Frustum[BACK][b],
m_Frustum[LEFT][C],m_Frustum[BOTTOM][C],m_Frustum[BACK][C],
-m_Frustum[LEFT][D],-m_Frustum[BOTTOM][D],-m_Frustum[BACK][D]
);

back_lower_right.x = CMy_math::get_x_from_equation33(
	m_Frustum[RIGHT][A],m_Frustum[BOTTOM][A],m_Frustum[BACK][A],
	m_Frustum[RIGHT][b],m_Frustum[BOTTOM][b],m_Frustum[BACK][b],
	m_Frustum[RIGHT][C],m_Frustum[BOTTOM][C],m_Frustum[BACK][C],
	-m_Frustum[RIGHT][D],-m_Frustum[BOTTOM][D],-m_Frustum[BACK][D]
	);
back_lower_right.y = CMy_math::get_y_from_equation33(
	m_Frustum[RIGHT][A],m_Frustum[BOTTOM][A],m_Frustum[BACK][A],
	m_Frustum[RIGHT][b],m_Frustum[BOTTOM][b],m_Frustum[BACK][b],
	m_Frustum[RIGHT][C],m_Frustum[BOTTOM][C],m_Frustum[BACK][C],
	-m_Frustum[RIGHT][D],-m_Frustum[BOTTOM][D],-m_Frustum[BACK][D]
	);
back_lower_right.z = -CMy_math::get_z_from_equation33(
	m_Frustum[RIGHT][A],m_Frustum[BOTTOM][A],m_Frustum[BACK][A],
	m_Frustum[RIGHT][b],m_Frustum[BOTTOM][b],m_Frustum[BACK][b],
	m_Frustum[RIGHT][C],m_Frustum[BOTTOM][C],m_Frustum[BACK][C],
	-m_Frustum[RIGHT][D],-m_Frustum[BOTTOM][D],-m_Frustum[BACK][D]
	);


back_upper_left.x = CMy_math::get_x_from_equation33(
	m_Frustum[LEFT][A],m_Frustum[TOP][A],m_Frustum[BACK][A],
	m_Frustum[LEFT][b],m_Frustum[TOP][b],m_Frustum[BACK][b],
	m_Frustum[LEFT][C],m_Frustum[TOP][C],m_Frustum[BACK][C],
	-m_Frustum[LEFT][D],-m_Frustum[TOP][D],-m_Frustum[BACK][D]
	);
back_upper_left.y = CMy_math::get_y_from_equation33(
	m_Frustum[LEFT][A],m_Frustum[TOP][A],m_Frustum[BACK][A],
	m_Frustum[LEFT][b],m_Frustum[TOP][b],m_Frustum[BACK][b],
	m_Frustum[LEFT][C],m_Frustum[TOP][C],m_Frustum[BACK][C],
	-m_Frustum[LEFT][D],-m_Frustum[TOP][D],-m_Frustum[BACK][D]
	);
back_upper_left.z = -CMy_math::get_z_from_equation33(
	m_Frustum[LEFT][A],m_Frustum[TOP][A],m_Frustum[BACK][A],
	m_Frustum[LEFT][b],m_Frustum[TOP][b],m_Frustum[BACK][b],
	m_Frustum[LEFT][C],m_Frustum[TOP][C],m_Frustum[BACK][C],
	-m_Frustum[LEFT][D],-m_Frustum[TOP][D],-m_Frustum[BACK][D]
	);


back_upper_right.x = CMy_math::get_x_from_equation33(
	m_Frustum[RIGHT][A],m_Frustum[TOP][A],m_Frustum[BACK][A],
	m_Frustum[RIGHT][b],m_Frustum[TOP][b],m_Frustum[BACK][b],
	m_Frustum[RIGHT][C],m_Frustum[TOP][C],m_Frustum[BACK][C],
	-m_Frustum[RIGHT][D],-m_Frustum[TOP][D],-m_Frustum[BACK][D]
	);
back_upper_right.y = CMy_math::get_y_from_equation33(
	m_Frustum[RIGHT][A],m_Frustum[TOP][A],m_Frustum[BACK][A],
	m_Frustum[RIGHT][b],m_Frustum[TOP][b],m_Frustum[BACK][b],
	m_Frustum[RIGHT][C],m_Frustum[TOP][C],m_Frustum[BACK][C],
	-m_Frustum[RIGHT][D],-m_Frustum[TOP][D],-m_Frustum[BACK][D]
	);
back_upper_right.z = -CMy_math::get_z_from_equation33(
	m_Frustum[RIGHT][A],m_Frustum[TOP][A],m_Frustum[BACK][A],
	m_Frustum[RIGHT][b],m_Frustum[TOP][b],m_Frustum[BACK][b],
	m_Frustum[RIGHT][C],m_Frustum[TOP][C],m_Frustum[BACK][C],
	-m_Frustum[RIGHT][D],-m_Frustum[TOP][D],-m_Frustum[BACK][D]
	);

/*static int count;
count ++;
if(count%30)
	dump_corners();
*/

}

Hmmm.
It seems a newer approach since you don’t invert any matrix.

I hope you get what you are looking for.