mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-08-30 23:40:16 +00:00
93 lines
2.9 KiB
C++
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;
|
|
}
|