www.pudn.com > zfxcengine-0.1.0.zip > ceFrustum.cpp


// $Id: ceFrustum.cpp,v 1.9 2005/09/05 08:52:19 kimmi Exp $ 
//////////////////////////////////////////////////////////////////////////////// 
// 
//	Module:		Math 
//	File:		ceFrustum.cpp 
//	Created:	16.01.2005 
//	Author:		Kim Kulling aka kimmi 
// 
//////////////////////////////////////////////////////////////////////////////// 
#include "Math/ceFrustum.h" 
 
namespace ZFXCE { 
	//------------------------------------------------------------------------------ 
	using namespace std; 
	const int NOF_POINT = 8; 
	const int NOF_PLANES = 6; 
	//------------------------------------------------------------------------------ 
	ceFrustum::ceFrustum() 
	{ 
		Init(); 
	} 
	//------------------------------------------------------------------------------ 
	ceFrustum::ceFrustum(ceMatrix &Matrix) 
	{ 
		Init(); 
		m_Matrix = Matrix; 
	} 
	//------------------------------------------------------------------------------ 
	ceFrustum::~ceFrustum() 
	{ 
		Release(); 
	} 
	//------------------------------------------------------------------------------ 
	void ceFrustum::Init() 
	{ 
		m_bGL_Update = true; 
		m_bD3D_Update = true; 
		m_Matrix.Identity(); 
		cePlane4f *pTemp = NULL; 
		for (UINT i = 0; i < NOF_PLANES; ++i) { 
			pTemp = new cePlane4f(); 
			ce_assert(NULL != pTemp); 
			m_vFrustumPlanes.push_back(pTemp); 
		} 
		for (UINT i=0; im_fA = m_Matrix._ms._41 + m_Matrix._ms._11; 
		m_vFrustumPlanes[0]->m_fB = m_Matrix._ms._42 + m_Matrix._ms._12; 
		m_vFrustumPlanes[0]->m_fC = m_Matrix._ms._43 + m_Matrix._ms._13; 
		m_vFrustumPlanes[0]->m_fD = m_Matrix._ms._44 + m_Matrix._ms._14; 
		 
		// Right 
		m_vFrustumPlanes[1]->m_fA = m_Matrix._ms._41 - m_Matrix._ms._11; 
		m_vFrustumPlanes[1]->m_fB = m_Matrix._ms._42 - m_Matrix._ms._12; 
		m_vFrustumPlanes[1]->m_fC = m_Matrix._ms._43 - m_Matrix._ms._13; 
		m_vFrustumPlanes[1]->m_fD = m_Matrix._ms._43 - m_Matrix._ms._14; 
		 
		// Top 
		m_vFrustumPlanes[2]->m_fA = m_Matrix._ms._41 - m_Matrix._ms._21; 
		m_vFrustumPlanes[2]->m_fB = m_Matrix._ms._42 - m_Matrix._ms._22; 
		m_vFrustumPlanes[2]->m_fC = m_Matrix._ms._43 - m_Matrix._ms._23; 
		m_vFrustumPlanes[2]->m_fD = m_Matrix._ms._44 - m_Matrix._ms._24; 
		 
		// Bottom 
		m_vFrustumPlanes[3]->m_fA = m_Matrix._ms._41 + m_Matrix._ms._21; 
		m_vFrustumPlanes[3]->m_fB = m_Matrix._ms._42 + m_Matrix._ms._22; 
		m_vFrustumPlanes[3]->m_fC = m_Matrix._ms._43 + m_Matrix._ms._23; 
		m_vFrustumPlanes[3]->m_fD = m_Matrix._ms._44 + m_Matrix._ms._24; 
		 
		// Near 
		m_vFrustumPlanes[4]->m_fA = m_Matrix._ms._41 + m_Matrix._ms._13; 
		m_vFrustumPlanes[4]->m_fB = m_Matrix._ms._42 + m_Matrix._ms._23; 
		m_vFrustumPlanes[4]->m_fC = m_Matrix._ms._43 + m_Matrix._ms._33; 
		m_vFrustumPlanes[4]->m_fD = m_Matrix._ms._44 + m_Matrix._ms._43; 
		 
		// Far 
		m_vFrustumPlanes[5]->m_fA = m_Matrix._ms._41 - m_Matrix._ms._13; 
		m_vFrustumPlanes[5]->m_fB = m_Matrix._ms._42 - m_Matrix._ms._23; 
		m_vFrustumPlanes[5]->m_fC = m_Matrix._ms._43 - m_Matrix._ms._33; 
		m_vFrustumPlanes[5]->m_fD = m_Matrix._ms._44 - m_Matrix._ms._43; 
		 
		// Normalize planes, if requested 
		if (bNormalized) { 
			for (UINT i=0; iNormalizePlane(); 
			} 
		} 
		 
		m_bGL_Update = false; 
 
		return true; 
	} 
	//------------------------------------------------------------------------------ 
	bool ceFrustum::ExtractPlanesD3D(bool bNormalized) 
	{ 
		if (!m_bD3D_Update) 
			return false; 
		 
		// Left 
		m_vFrustumPlanes[0]->m_fA = m_Matrix._ms._14 + m_Matrix._ms._11; 
		m_vFrustumPlanes[0]->m_fB = m_Matrix._ms._24 + m_Matrix._ms._21; 
		m_vFrustumPlanes[0]->m_fC = m_Matrix._ms._34 + m_Matrix._ms._31; 
		m_vFrustumPlanes[0]->m_fD = m_Matrix._ms._44 + m_Matrix._ms._41; 
		 
		// Right 
		m_vFrustumPlanes[1]->m_fA = m_Matrix._ms._14 - m_Matrix._ms._11; 
		m_vFrustumPlanes[1]->m_fB = m_Matrix._ms._24 - m_Matrix._ms._21; 
		m_vFrustumPlanes[1]->m_fC = m_Matrix._ms._34 - m_Matrix._ms._31; 
		m_vFrustumPlanes[1]->m_fD = m_Matrix._ms._44 - m_Matrix._ms._41; 
		 
		// Top 
		m_vFrustumPlanes[2]->m_fA = m_Matrix._ms._14 - m_Matrix._ms._12; 
		m_vFrustumPlanes[2]->m_fB = m_Matrix._ms._24 - m_Matrix._ms._22; 
		m_vFrustumPlanes[2]->m_fC = m_Matrix._ms._34 - m_Matrix._ms._32; 
		m_vFrustumPlanes[2]->m_fD = m_Matrix._ms._44 - m_Matrix._ms._42; 
		 
		// Bottom 
		m_vFrustumPlanes[3]->m_fA = m_Matrix._ms._14 + m_Matrix._ms._12; 
		m_vFrustumPlanes[3]->m_fB = m_Matrix._ms._24 + m_Matrix._ms._22; 
		m_vFrustumPlanes[3]->m_fC = m_Matrix._ms._34 + m_Matrix._ms._32; 
		m_vFrustumPlanes[3]->m_fD = m_Matrix._ms._44 + m_Matrix._ms._42; 
		 
		// Near 
		m_vFrustumPlanes[4]->m_fA = m_Matrix._ms._13; 
		m_vFrustumPlanes[4]->m_fB = m_Matrix._ms._23; 
		m_vFrustumPlanes[4]->m_fC = m_Matrix._ms._33; 
		m_vFrustumPlanes[4]->m_fD = m_Matrix._ms._43; 
		 
		// Far 
		m_vFrustumPlanes[5]->m_fA = m_Matrix._ms._14 - m_Matrix._ms._13; 
		m_vFrustumPlanes[5]->m_fB = m_Matrix._ms._24 - m_Matrix._ms._23; 
		m_vFrustumPlanes[5]->m_fC = m_Matrix._ms._34 - m_Matrix._ms._33; 
		m_vFrustumPlanes[5]->m_fD = m_Matrix._ms._44 - m_Matrix._ms._43; 
		 
		// Normalize planes, if requested 
		if (bNormalized) { 
			for (UINT i=0; iNormalizePlane(); 
			} 
		} 
		 
		m_bD3D_Update = false; 
	 
		return true; 
	} 
	//------------------------------------------------------------------------------ 
	void ceFrustum::SetModelViewMatrix(ceMatrix &Matrix) 
	{  
		m_Matrix = Matrix;  
		m_bGL_Update = true; 
		m_bD3D_Update = true;	 
	} 
	//------------------------------------------------------------------------------ 
	ceHalfSpace ceFrustum::ContainsAABB(ceAABB &AABB) 
	{ 
		// Get the corners of the box into the vCorner array 
		ce_assert (NOF_PLANES == m_vFrustumPlanes.size()); 
		 
		std::vector Corner; 
		AABB.GetVertices(Corner); 
		ce_assert (NOF_POINT == Corner.size()); 
		int iTotalIn = 0; 
 
		// Test all 8 corners against the 6 sides  
		// If all points are behind 1 specific plane, we are out 
		// If we are in with all points, then we are fully in 
		for (size_t p = 0; p < m_vFrustumPlanes.size(); ++p) { 
			int iInCount = NOF_POINT; 
			int iPtIn = 1; 
			for (size_t i = 0; i < Corner.size(); ++i) { 
				// Test this point against the planes 
				ce_assert (NULL != m_vFrustumPlanes[p]); 
				if (PLANE_NEGATIVE == m_vFrustumPlanes[p]->ClassifyPoint(Corner[i])) { 
					iPtIn = 0; 
					--iInCount; 
				} 
			} 
 
			// Were all the points outside of plane p? 
			if (0 == iInCount) { 
				return PLANE_OUTSIDE; 
			} 
 
			// check if they were all on the right side of the plane 
			iTotalIn += iPtIn; 
		} 
 
		// so if iTotalIn is 6, then all are inside the view 
		if (NOF_PLANES == iTotalIn) 
			return PLANE_POSITIVE; 
 
		// we must be partly in then otherwise 
		return PLANE_ONPLANE; 
	} 
	//------------------------------------------------------------------------------ 
 
} // Namespace ZFXCE