Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | Namespace Members | Class Members | Related Pages

Frustum Class Reference
[XEngineMath Library]

Inheritance diagram for Frustum:

Inheritance graph
[legend]
List of all members.

Detailed Description

This class represents a pyramidal frustum which is defined as the volume created by 6 planes where always 3 planes intersect each other to form the 8 corner points of the frustum. The front and back plane of the frustum must be parallel to each other. In other words, this class represents a cut off pyramid that can have any quadrilateral as base.

Internally, the Frustum class stores the 6 planes and not the 8 corner vertices, although it is possible to create a frustum specifying only the corner vertices.

The internally stored planes are stored in the following order:

The normals of these planes point away from the frustum. Or in other words, the positive normals point towards the outside of the frustum, and the negative normals point inside the frustum. This is the default assumption for plane normals in XEngine.


Public Member Functions

 Frustum ()
 Default constructor.
 Frustum (const boost::array< Plane, 6 > &planes)
 Constructs a frustum from the given 6 planes.
template<typename InputIteratorT>
 Frustum (InputIteratorT it)
 Constructs a frustum from the given 6 planes.
void Set (const boost::array< Plane, 6 > &planes)
 Sets all the planes of this frustum.
template<typename InputIteratorT>
void Set (InputIteratorT it)
 Sets all the planes of this frustum.
void SetPlane (size_t index, const Plane &plane)
 Sets one of the planes of this frustum.
const PlaneGetPlane (size_t index) const
 Returns one of the planes that make up this frustum.
template<typename OutputIteratorT>
void GetPlanes (OutputIteratorT it)
 Returns all the 6 planes that make up this frustum.
template<typename InputIteratorT>
void SetCornerVertices (InputIteratorT it)
 Sets this frustum to a new frustum defined by the 8 given corner vertices.
template<typename OutputIteratorT>
void GetCornerVertices (OutputIteratorT it) const
 Returns the 8 corner vertices of this frustum.
Vector3 GetCornerVertex (size_t index) const
 Returns one of the 8 corner vertices of this frustum.
void SetFromProjectionMatrix (const Matrix4x4 &m)
 Sets this frustum to represent the given projection matrix.
Matrix4x4 GetAsProjectionMatrix () const
 Returns a projection matrix representation of this frustum.
bool operator== (const Frustum &f) const
 Equality operator.
bool operator!= (const Frustum &f) const
 Inequality operator.
virtual void Transform (const Matrix4x4 &m)
 Transforms this object by the given matrix.
virtual void Transform (const Math::Transform &m)
 Transforms this object by the given affine transform.
virtual real GetVolume () const
 Returns the volume of this object.
virtual bool Contains (const Point< 3 > &point) const
 Returns true if this volume contains the given point.


Constructor & Destructor Documentation

Frustum  ) 
 

Default constructor.

Warning:
Does not initialize the frustum.

Frustum const boost::array< Plane, 6 > &  planes  )  [explicit]
 

Constructs a frustum from the given 6 planes. Make sure that none of the planes are equal to one another and that the 6 planes really form a frustum. No check is performed for this, but you will get very weird results if you use a frustum that has incorrectly set planes. The only thing that is checked with an assert in the debug build of the engine is that the front and back plane are parallel to each other. Also note that the positive normals of the planes must point outside the frustum.

The 6 planes have to be given in the following order:

  • left
  • right
  • bottom
  • top
  • back
  • front

Frustum InputIteratorT  it  )  [explicit]
 

Constructs a frustum from the given 6 planes using the given Plane input iterator. Make sure that none of the planes are equal to one another and that the 6 planes really form a frustum. No check is performed for this, but you will get very weird results if you use a frustum that has incorrectly set planes. The only thing that is checked with an assert in the debug build of the engine is that the front and back plane are parallel to each other. Also note that the positive normals of the planes must point outside the frustum.

The 6 planes have to be given in the following order:

  • left
  • right
  • bottom
  • top
  • back
  • front


Member Function Documentation

bool Contains const Point< 3 > &  point  )  const [virtual]
 

Returns true if this frustum contains the given point. The point lies within the frustum if it is on the negative (= inside) side of all frustum planes.

Implements Volume.

Matrix4x4 GetAsProjectionMatrix  )  const
 

Returns a matrix representation of this frustum. The returned matrix will be some kind of projection matrix. Note however, that it might also contain various rotations and translations, depending on the position of the frustum in its local coordinate system.

Vector3 GetCornerVertex size_t  index  )  const
 

Returns one of the 8 corner vertices of this frustum. The given index corresponds to the vertices of the frustum as follows:

  • Index 0 = left, bottom, back
  • Index 1 = right, bottom, back
  • Index 2 = left, top, back
  • Index 3 = right, top, back
  • Index 4 = left, bottom, front
  • Index 5 = right, bottom, front
  • Index 6 = left, top, front
  • Index 7 = right, top, front

void GetCornerVertices OutputIteratorT  it  )  const
 

Returns the 8 corner vertices of this frustum using the given Vector3 output iterator.

The 8 points are returned in the following order:

  • left, bottom, back
  • right, bottom, back
  • left, top, back
  • right, top, back
  • left, bottom, front
  • right, bottom, front
  • left, top, front
  • right, top, front

const Plane & GetPlane size_t  index  )  const
 

Returns one of the planes that make up this frustum.

The planes' indices correspond to the planes as follows:

  • 0 = left
  • 1 = right
  • 2 = bottom
  • 3 = top
  • 4 = back
  • 5 = front

void GetPlanes OutputIteratorT  it  ) 
 

Returns all the 6 planes that make up this frustum using the given Plane output iterator.

The planes are returned in the given array in the following order:

  • left
  • right
  • bottom
  • top
  • back
  • front

real GetVolume  )  const [virtual]
 

Returns the volume of this frustum.

	If the frustum's side planes (the left, right, bottom and top planes) do 
	not intersect, then the frustum is actually a prism, and its volume is 
	simply the area of the quadrilateral formed by the four points of the 
	frustum on either the front or back plane multiplied by the distance from 
	the front to the back plane.
	The area of that quadrilateral is A = ((e * f) / 2) * sin(phi)	where 
	e and f are the lengths of the diagonals of the quadrilateral and phi is 
	the angle between those diagonals.

	If the frustum's side planes (the left, right, bottom and top planes) 
	intersect at one point, then the frustum is not a prism and we can
	use the general formula for a pyramidal frustum to calculate the volume,
	since according to Cavalieri's Principle the volume of a skewed or
	asymmetric pyramid is the same as the volume of the straight, symmetric
	pyramid with the same base quadrilateral and height.
	The volume of the frustum therefore is:
		V = (h / 3) * (B + sqrt(B * A) + A)
	where h is the distance from the front to the back plane, A is the
	area of the quadrilateral on the front plane and B is the area of the
	quadrilateral on the back plane.
	

Implements Volume.

bool operator!= const Frustum f  )  const
 

Inequality operator.

bool operator== const Frustum f  )  const
 

Equality operator.

void Set InputIteratorT  it  ) 
 

Sets all the planes of this frustum using the given Plane input iterator. Make sure that the given 6 planes describe a non-degenerated frustum. The front and back planes must be parallel to each other and none of the planes must be equal to one of the other planes. Also note that the positive normals of the planes must point outside the frustum.

The planes need to be given in the following order:

  • left
  • right
  • bottom
  • top
  • back
  • front

void Set const boost::array< Plane, 6 > &  planes  ) 
 

Sets all the planes of this frustum. Make sure that the given 6 planes describe a non-degenerated frustum. The front and back planes must be parallel to each other and none of the planes must be equal to one of the other planes. Also note that the positive normals of the planes must point outside the frustum.

The planes need to be given in the following order:

  • left
  • right
  • bottom
  • top
  • back
  • front

void SetCornerVertices InputIteratorT  it  ) 
 

Sets this frustum to a new frustum defined by the 8 given corner vertices by the given Vector3 input iterator.

The 8 points have to be given in the following order:

  • left, bottom, back
  • right, bottom, back
  • left, top, back
  • right, top, back
  • left, bottom, front
  • right, bottom, front
  • left, top, front
  • right, top, front

void SetFromProjectionMatrix const Matrix4x4 m  ) 
 

Sets this frustum to represent the given projection matrix. If the projection matrix is a pure projection matrix then the frustum will be in view space. You can also pass in the combined view-projection matrix V * P to extract the frustum in world coordinates, or the combined world-view-projection matrix W * V * P to extract the frustum in model coordinates.

	In clipping space the frustum is actually a cube defined by the following
	inequalities in XEngine:
		-1 < x < 1
		-1 < y < 1
		 0 < z < 1

	Let M be the given 4x4 matrix which performs a projection, then the 
	transformation of a point P = [x, y, z, w] to clipping space is done
	by multiplying P by M:

	                             [ m00 m01 m02 m03 ]   [ P * M_column0 ]
	P' = P * M = [x, y, z, w] *  [ m10 m11 m12 m13 ] = [ P * M_column1 ]
	                             [ m20 m21 m22 m23 ]   [ P * M_column2 ]
	                             [ m30 m31 m32 m33 ]   [ P * M_column3 ]

	Now we know that the transformed point P' = [x', y', z', w'] is inside the 
	frustum if the inequalities above hold for P'. Furthermore we can draw 
	some more conclusions by looking at the inequalities individually:
	- If -w' < x' then x' is in the inside half-space of the left frustum plane.
	- If x' < w' then x' is in the inside half-space of the right frustum plane.
	- If -w' < y' then y' is in the inside half-space of the bottom frustum plane.
	- If y' < w' then y' is in the inside half-space of the top frustum plane.
	- If 0 < z' then z' is in the inside half-space of the front frustum plane.
	- If z' < w' then z' is in the inside half-space of the back frustum plane.
	
	So to test whether x' lies in the inside half-space of the left frustum plane
	we'd have to test whether 
		-w' < x'
	which can be rewritten as 
		-P * M_column3 < P * M_column0      <==>
		-P * M_column3 - P * M_column0 < 0  <==>
		P * (-M_column3 - M_column0) < 0
	which is already the plane equation of the left frustum plane of the 
	untransformed frustum:
		x * (-m03 - m00) + y * (-m13 - m10) + y * (-m23 - m20) + w * (-m33 - m30) = 0
	Since P is a point in homogeneous coordinates we know that w = 1
	and therefore:
		x * (-m03 - m00) + y * (-m13 - m10) + y * (-m23 - m20) + (-m33 - m30) = 0
	Writing this in the form n * X = d gives us
		[-m03 - m00, -m13 - m10, -m23 - m20] * X = m33 + m30
	Note that, as always in XEngine, the normal of the plane points towards the
	outside of the frustum. Also note that the retrieved plane as shown above
	is not necessarily normalized. Internally XEngine normalizes the planes
	however.

	We can now extract all the other planes in a similar way to get:
	- Left plane:     [-m03 - m00, -m13 - m10, -m23 - m20] * X = m33 + m30
	- Right plane:    [m00 - m03, m10 - m13, m20 - m23]    * X = -m30 + m33
	- Bottom plane:   [-m03 - m01, -m13 - m11, -m23 - m21] * X = m33 + m31
	- Top plane:      [m01 - m03, m11 - m13, m21 - m23]    * X = -m31 + m33
	- Front plane:    [-m02, -m12, -m22]                   * X = m32
	- Back plane:     [m02 - m03, m12 - m13, m22 - m23]    * X = -m32 + m33
	

void SetPlane size_t  index,
const Plane plane
 

Sets one of the planes of this frustum. Make sure that setting the plane does not degenerate the frustum (for example, if the new plane is equal to one of the other already set planes, or if you try to set the back plane and it is no longer parallel to the front plane). Also note that the positive normals of the planes must point outside the frustum.

The planes' indices correspond to the planes as follows:

  • 0 = left
  • 1 = right
  • 2 = bottom
  • 3 = top
  • 4 = back
  • 5 = front

void Transform const Math::Transform m  )  [virtual]
 

Transforms this frustum by the given affine transform.

Reimplemented from GeometricObject3.

void Transform const Matrix4x4 m  )  [virtual]
 

Transforms this frustum by the given matrix.

Implements GeometricObject3.


The documentation for this class was generated from the following files: