1
0
forked from 0ad/0ad
0ad/source/terrain/Frustum.cpp
janwas 5cc814759f Initial revision
This was SVN commit r9.
2003-11-03 16:22:45 +00:00

145 lines
2.8 KiB
C++
Executable File

//***********************************************************
//
// Name: Frustum.Cpp
// Last Update: 24/2/02
// Author: Poya Manouchehri
//
// Description: CFrustum is a collection of planes which define
// a viewing space. Usually associated with the
// camera, there are 6 planes which define the
// view pyramid. But we allow more planes per
// frustum which maybe used for portal rendering,
// where a portal may have 3 or more edges.
//
//***********************************************************
#include "Frustum.H"
CFrustum::CFrustum ()
{
m_NumPlanes = 0;
}
CFrustum::~CFrustum ()
{
}
void CFrustum::SetNumPlanes (int num)
{
m_NumPlanes = num;
//clip it
if (m_NumPlanes >= MAX_NUM_FRUSTUM_PLANES)
m_NumPlanes = MAX_NUM_FRUSTUM_PLANES-1;
else if (m_NumPlanes < 0)
m_NumPlanes = 0;
}
bool CFrustum::IsPointVisible (CVector3D &point)
{
PLANESIDE Side;
for (int i=0; i<m_NumPlanes; i++)
{
Side = m_aPlanes[i].ClassifyPoint (point);
if (Side == PS_BACK)
return false;
}
return true;
}
bool CFrustum::IsSphereVisible (CVector3D &center, float radius)
{
for (int i=0; i<m_NumPlanes; i++)
{
float Dist = m_aPlanes[i].DistanceToPlane (center);
//is it behind the plane
if (Dist < 0)
{
//if non of it falls in front its outside the
//frustum
if (-Dist > radius)
return false;
}
}
return true;
}
bool CFrustum::IsBoxVisible (CVector3D &position, SBoundingBox &bounds)
{
//basically for every plane we calculate the furthust point
//in the box to that plane. If that point is beyond the plane
//then the box is not visible
CVector3D FarPoint;
PLANESIDE Side;
CVector3D Min = position+bounds.m_BoxMin;
CVector3D Max = position+bounds.m_BoxMax;
for (int i=0; i<m_NumPlanes; i++)
{
if (m_aPlanes[i].m_Norm.X > 0.0f)
{
if (m_aPlanes[i].m_Norm.Y > 0.0f)
{
if (m_aPlanes[i].m_Norm.Z > 0.0f)
{
FarPoint.X = Max.X; FarPoint.Y = Max.Y; FarPoint.Z = Max.Z;
}
else
{
FarPoint.X = Max.X; FarPoint.Y = Max.Y; FarPoint.Z = Min.Z;
}
}
else
{
if (m_aPlanes[i].m_Norm.Z > 0.0f)
{
FarPoint.X = Max.X; FarPoint.Y = Min.Y; FarPoint.Z = Max.Z;
}
else
{
FarPoint.X = Max.X; FarPoint.Y = Min.Y; FarPoint.Z = Min.Z;
}
}
}
else
{
if (m_aPlanes[i].m_Norm.Y > 0.0f)
{
if (m_aPlanes[i].m_Norm.Z > 0.0f)
{
FarPoint.X = Min.X; FarPoint.Y = Max.Y; FarPoint.Z = Max.Z;
}
else
{
FarPoint.X = Min.X; FarPoint.Y = Max.Y; FarPoint.Z = Min.Z;
}
}
else
{
if (m_aPlanes[i].m_Norm.Z > 0.0f)
{
FarPoint.X = Min.X; FarPoint.Y = Min.Y; FarPoint.Z = Max.Z;
}
else
{
FarPoint.X = Min.X; FarPoint.Y = Min.Y; FarPoint.Z = Min.Z;
}
}
}
Side = m_aPlanes[i].ClassifyPoint (FarPoint);
if (Side == PS_BACK)
return false;
}
return true;
}