PrimeWorldEditor/src/Math/CFrustumPlanes.cpp
2016-03-27 13:09:38 -06:00

93 lines
2.9 KiB
C++

#include "CFrustumPlanes.h"
#include "MathUtil.h"
#include "Common/types.h"
CFrustumPlanes::CFrustumPlanes()
{
}
const CPlane& CFrustumPlanes::GetPlane(EFrustumSide Side) const
{
return mPlanes[Side];
}
void CFrustumPlanes::SetPlanes(const CVector3f& rkPosition, const CVector3f& rkDirection, float FieldOfView, float AspectRatio, float Near, float Far)
{
// Calculate up/right vectors
CVector3f Right = rkDirection.Cross(CVector3f::skUp).Normalized();
CVector3f Up = Right.Cross(rkDirection).Normalized();
// Calculate dimensions of near plane
float NearHeight = 2 * tanf(Math::DegreesToRadians(FieldOfView) / 2.f) * Near;
float NearWidth = NearHeight * AspectRatio;
// Define the planes
CVector3f NearCenter = rkPosition + (rkDirection * Near);
mPlanes[eNearPlane].Redefine(rkDirection, NearCenter);
CVector3f FarCenter = rkPosition + (rkDirection * Far);
mPlanes[eFarPlane].Redefine(-rkDirection, FarCenter);
CVector3f MidRight = NearCenter + (Right * (NearWidth / 2.f));
CVector3f RightNormal = Up.Cross((MidRight - rkPosition).Normalized());
mPlanes[eRightPlane].Redefine(RightNormal, rkPosition);
CVector3f MidLeft = NearCenter - (Right * (NearWidth / 2.f));
CVector3f LeftNormal = (MidLeft - rkPosition).Normalized().Cross(Up);
mPlanes[eLeftPlane].Redefine(LeftNormal, rkPosition);
CVector3f MidTop = NearCenter + (Up * (NearHeight / 2.f));
CVector3f TopNormal = (MidTop - rkPosition).Normalized().Cross(Right);
mPlanes[eTopPlane].Redefine(TopNormal, rkPosition);
CVector3f MidBottom = NearCenter - (Up * (NearHeight / 2.f));
CVector3f BottomNormal = Right.Cross((MidBottom - rkPosition).Normalized());
mPlanes[eBottomPlane].Redefine(BottomNormal, rkPosition);
}
bool CFrustumPlanes::PointInFrustum(const CVector3f& rkPoint) const
{
for (u32 iPlane = 0; iPlane < 6; iPlane++)
{
const CPlane& rkPlane = mPlanes[iPlane];
if (rkPlane.Normal().Dot(rkPoint) + rkPlane.Dist() < 0.f)
return false;
}
return true;
}
bool CFrustumPlanes::BoxInFrustum(const CAABox& rkBox) const
{
CVector3f Min = rkBox.Min();
CVector3f Max = rkBox.Max();
CVector3f Points[8];
Points[0] = Min;
Points[1] = Max;
Points[2] = CVector3f(Min.X, Min.Y, Max.Z);
Points[3] = CVector3f(Min.X, Max.Y, Min.Z);
Points[4] = CVector3f(Min.X, Max.Y, Max.Z);
Points[5] = CVector3f(Max.X, Min.Y, Max.Z);
Points[6] = CVector3f(Max.X, Max.Y, Min.Z);
Points[7] = CVector3f(Max.X, Min.Y, Min.Z);
for (u32 iPlane = 0; iPlane < 6; iPlane++)
{
const CPlane& rkPlane = mPlanes[iPlane];
int NumPoints = 0;
for (u32 iPoint = 0; iPoint < 8; iPoint++)
{
if (rkPlane.Normal().Dot(Points[iPoint]) + rkPlane.Dist() < 0.f)
NumPoints++;
else
break;
}
if (NumPoints == 8) return false;
}
return true;
}