forked from 0ad/0ad
145 lines
2.8 KiB
C++
Executable File
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 ¢er, 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;
|
|
}
|
|
|