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