Cleanups Frustum and removes access to members.

This was SVN commit r25158.
This commit is contained in:
vladislavbelov
2021-03-29 17:15:29 +00:00
parent e5b971c2bf
commit 4f83f1a0e9
4 changed files with 91 additions and 100 deletions
+25 -25
View File
@@ -105,43 +105,43 @@ void CCamera::UpdateFrustum(const CBoundingBoxAligned& scissor)
m_ViewFrustum.SetNumPlanes(6);
// get the RIGHT plane
m_ViewFrustum.m_aPlanes[0].m_Norm.X = scissor[1].X*MatFinal._41 - MatFinal._11;
m_ViewFrustum.m_aPlanes[0].m_Norm.Y = scissor[1].X*MatFinal._42 - MatFinal._12;
m_ViewFrustum.m_aPlanes[0].m_Norm.Z = scissor[1].X*MatFinal._43 - MatFinal._13;
m_ViewFrustum.m_aPlanes[0].m_Dist = scissor[1].X*MatFinal._44 - MatFinal._14;
m_ViewFrustum[0].m_Norm.X = scissor[1].X*MatFinal._41 - MatFinal._11;
m_ViewFrustum[0].m_Norm.Y = scissor[1].X*MatFinal._42 - MatFinal._12;
m_ViewFrustum[0].m_Norm.Z = scissor[1].X*MatFinal._43 - MatFinal._13;
m_ViewFrustum[0].m_Dist = scissor[1].X*MatFinal._44 - MatFinal._14;
// get the LEFT plane
m_ViewFrustum.m_aPlanes[1].m_Norm.X = -scissor[0].X*MatFinal._41 + MatFinal._11;
m_ViewFrustum.m_aPlanes[1].m_Norm.Y = -scissor[0].X*MatFinal._42 + MatFinal._12;
m_ViewFrustum.m_aPlanes[1].m_Norm.Z = -scissor[0].X*MatFinal._43 + MatFinal._13;
m_ViewFrustum.m_aPlanes[1].m_Dist = -scissor[0].X*MatFinal._44 + MatFinal._14;
m_ViewFrustum[1].m_Norm.X = -scissor[0].X*MatFinal._41 + MatFinal._11;
m_ViewFrustum[1].m_Norm.Y = -scissor[0].X*MatFinal._42 + MatFinal._12;
m_ViewFrustum[1].m_Norm.Z = -scissor[0].X*MatFinal._43 + MatFinal._13;
m_ViewFrustum[1].m_Dist = -scissor[0].X*MatFinal._44 + MatFinal._14;
// get the BOTTOM plane
m_ViewFrustum.m_aPlanes[2].m_Norm.X = -scissor[0].Y*MatFinal._41 + MatFinal._21;
m_ViewFrustum.m_aPlanes[2].m_Norm.Y = -scissor[0].Y*MatFinal._42 + MatFinal._22;
m_ViewFrustum.m_aPlanes[2].m_Norm.Z = -scissor[0].Y*MatFinal._43 + MatFinal._23;
m_ViewFrustum.m_aPlanes[2].m_Dist = -scissor[0].Y*MatFinal._44 + MatFinal._24;
m_ViewFrustum[2].m_Norm.X = -scissor[0].Y*MatFinal._41 + MatFinal._21;
m_ViewFrustum[2].m_Norm.Y = -scissor[0].Y*MatFinal._42 + MatFinal._22;
m_ViewFrustum[2].m_Norm.Z = -scissor[0].Y*MatFinal._43 + MatFinal._23;
m_ViewFrustum[2].m_Dist = -scissor[0].Y*MatFinal._44 + MatFinal._24;
// get the TOP plane
m_ViewFrustum.m_aPlanes[3].m_Norm.X = scissor[1].Y*MatFinal._41 - MatFinal._21;
m_ViewFrustum.m_aPlanes[3].m_Norm.Y = scissor[1].Y*MatFinal._42 - MatFinal._22;
m_ViewFrustum.m_aPlanes[3].m_Norm.Z = scissor[1].Y*MatFinal._43 - MatFinal._23;
m_ViewFrustum.m_aPlanes[3].m_Dist = scissor[1].Y*MatFinal._44 - MatFinal._24;
m_ViewFrustum[3].m_Norm.X = scissor[1].Y*MatFinal._41 - MatFinal._21;
m_ViewFrustum[3].m_Norm.Y = scissor[1].Y*MatFinal._42 - MatFinal._22;
m_ViewFrustum[3].m_Norm.Z = scissor[1].Y*MatFinal._43 - MatFinal._23;
m_ViewFrustum[3].m_Dist = scissor[1].Y*MatFinal._44 - MatFinal._24;
// get the FAR plane
m_ViewFrustum.m_aPlanes[4].m_Norm.X = scissor[1].Z*MatFinal._41 - MatFinal._31;
m_ViewFrustum.m_aPlanes[4].m_Norm.Y = scissor[1].Z*MatFinal._42 - MatFinal._32;
m_ViewFrustum.m_aPlanes[4].m_Norm.Z = scissor[1].Z*MatFinal._43 - MatFinal._33;
m_ViewFrustum.m_aPlanes[4].m_Dist = scissor[1].Z*MatFinal._44 - MatFinal._34;
m_ViewFrustum[4].m_Norm.X = scissor[1].Z*MatFinal._41 - MatFinal._31;
m_ViewFrustum[4].m_Norm.Y = scissor[1].Z*MatFinal._42 - MatFinal._32;
m_ViewFrustum[4].m_Norm.Z = scissor[1].Z*MatFinal._43 - MatFinal._33;
m_ViewFrustum[4].m_Dist = scissor[1].Z*MatFinal._44 - MatFinal._34;
// get the NEAR plane
m_ViewFrustum.m_aPlanes[5].m_Norm.X = -scissor[0].Z*MatFinal._41 + MatFinal._31;
m_ViewFrustum.m_aPlanes[5].m_Norm.Y = -scissor[0].Z*MatFinal._42 + MatFinal._32;
m_ViewFrustum.m_aPlanes[5].m_Norm.Z = -scissor[0].Z*MatFinal._43 + MatFinal._33;
m_ViewFrustum.m_aPlanes[5].m_Dist = -scissor[0].Z*MatFinal._44 + MatFinal._34;
m_ViewFrustum[5].m_Norm.X = -scissor[0].Z*MatFinal._41 + MatFinal._31;
m_ViewFrustum[5].m_Norm.Y = -scissor[0].Z*MatFinal._42 + MatFinal._32;
m_ViewFrustum[5].m_Norm.Z = -scissor[0].Z*MatFinal._43 + MatFinal._33;
m_ViewFrustum[5].m_Dist = -scissor[0].Z*MatFinal._44 + MatFinal._34;
for (size_t i = 0; i < 6; ++i)
m_ViewFrustum.m_aPlanes[i].Normalize();
m_ViewFrustum[i].Normalize();
}
void CCamera::ClipFrustum(const CPlane& clipPlane)
+37 -41
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2009 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -15,10 +15,6 @@
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* 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 may be used for
@@ -28,28 +24,28 @@ portal rendering, where a portal may have 3 or more edges.
#include "precompiled.h"
#include "Frustum.h"
#include "maths/BoundingBoxAligned.h"
#include "maths/MathUtil.h"
#include "maths/Matrix3D.h"
CFrustum::CFrustum ()
CFrustum::CFrustum()
{
m_NumPlanes = 0;
}
CFrustum::~CFrustum ()
CFrustum::~CFrustum()
{
}
void CFrustum::SetNumPlanes (size_t num)
void CFrustum::SetNumPlanes(size_t num)
{
m_NumPlanes = num;
//clip it
if (m_NumPlanes >= MAX_NUM_FRUSTUM_PLANES)
{
debug_warn(L"CFrustum::SetNumPlanes: Too many planes");
m_NumPlanes = MAX_NUM_FRUSTUM_PLANES-1;
m_NumPlanes = MAX_NUM_FRUSTUM_PLANES - 1;
}
}
@@ -61,25 +57,25 @@ void CFrustum::AddPlane(const CPlane& plane)
return;
}
m_aPlanes[m_NumPlanes++] = plane;
m_Planes[m_NumPlanes++] = plane;
}
void CFrustum::Transform(CMatrix3D& m)
void CFrustum::Transform(const CMatrix3D& m)
{
for (size_t i = 0; i < m_NumPlanes; ++i)
{
CVector3D n = m.Rotate(m_aPlanes[i].m_Norm);
CVector3D p = m.Transform(m_aPlanes[i].m_Norm * -m_aPlanes[i].m_Dist);
m_aPlanes[i].Set(n, p);
m_aPlanes[i].Normalize();
CVector3D n = m.Rotate(m_Planes[i].m_Norm);
CVector3D p = m.Transform(m_Planes[i].m_Norm * -m_Planes[i].m_Dist);
m_Planes[i].Set(n, p);
m_Planes[i].Normalize();
}
}
bool CFrustum::IsPointVisible(const CVector3D& point) const
{
for (size_t i=0; i<m_NumPlanes; ++i)
for (size_t i = 0; i < m_NumPlanes; ++i)
{
if (m_aPlanes[i].IsPointOnBackSide(point))
if (m_Planes[i].IsPointOnBackSide(point))
return false;
}
@@ -91,13 +87,13 @@ bool CFrustum::DoesSegmentIntersect(const CVector3D& startRef, const CVector3D&
CVector3D start = startRef;
CVector3D end = endRef;
if(IsPointVisible(start) || IsPointVisible(end))
if (IsPointVisible(start) || IsPointVisible(end))
return true;
CVector3D intersect;
for (size_t i = 0; i<m_NumPlanes; ++i)
for (size_t i = 0; i < m_NumPlanes; ++i)
{
if (m_aPlanes[i].FindLineSegIntersection(start, end, &intersect))
if (m_Planes[i].FindLineSegIntersection(start, end, &intersect))
{
if (IsPointVisible(intersect))
return true;
@@ -111,8 +107,8 @@ bool CFrustum::IsSphereVisible(const CVector3D& center, float radius) const
for (size_t i = 0; i < m_NumPlanes; ++i)
{
// If none of the sphere is in front of the plane, then
// it is outside the frustum
if (-m_aPlanes[i].DistanceToPlane(center) > radius)
// it is outside the frustum.
if (-m_Planes[i].DistanceToPlane(center) > radius)
return false;
}
@@ -121,20 +117,20 @@ bool CFrustum::IsSphereVisible(const CVector3D& center, float radius) const
bool CFrustum::IsBoxVisible(const CVector3D& position, const CBoundingBoxAligned& bounds) const
{
//basically for every plane we calculate the furthest point
//in the box to that plane. If that point is beyond the plane
//then the box is not visible
CVector3D FarPoint;
CVector3D Min = position+bounds[0];
CVector3D Max = position+bounds[1];
// Basically for every plane we calculate the furthest point
// in the box to that plane. If that point is beyond the plane
// then the box is not visible.
CVector3D farPoint;
CVector3D minPoint = position + bounds[0];
CVector3D maxPoint = position + bounds[1];
for (size_t i=0; i<m_NumPlanes; ++i)
for (size_t i = 0; i < m_NumPlanes; ++i)
{
FarPoint.X = m_aPlanes[i].m_Norm.X > 0.0f ? Max.X : Min.X;
FarPoint.Y = m_aPlanes[i].m_Norm.Y > 0.0f ? Max.Y : Min.Y;
FarPoint.Z = m_aPlanes[i].m_Norm.Z > 0.0f ? Max.Z : Min.Z;
farPoint.X = m_Planes[i].m_Norm.X > 0.0f ? maxPoint.X : minPoint.X;
farPoint.Y = m_Planes[i].m_Norm.Y > 0.0f ? maxPoint.Y : minPoint.Y;
farPoint.Z = m_Planes[i].m_Norm.Z > 0.0f ? maxPoint.Z : minPoint.Z;
if (m_aPlanes[i].IsPointOnBackSide(FarPoint))
if (m_Planes[i].IsPointOnBackSide(farPoint))
return false;
}
@@ -143,16 +139,16 @@ bool CFrustum::IsBoxVisible(const CVector3D& position, const CBoundingBoxAligned
bool CFrustum::IsBoxVisible(const CBoundingBoxAligned& bounds) const
{
//Same as the previous one, but with the position = (0, 0, 0)
CVector3D FarPoint;
// Same as the previous one, but with the position = (0, 0, 0).
CVector3D farPoint;
for (size_t i=0; i<m_NumPlanes; ++i)
for (size_t i = 0; i < m_NumPlanes; ++i)
{
FarPoint.X = m_aPlanes[i].m_Norm.X > 0.0f ? bounds[1].X : bounds[0].X;
FarPoint.Y = m_aPlanes[i].m_Norm.Y > 0.0f ? bounds[1].Y : bounds[0].Y;
FarPoint.Z = m_aPlanes[i].m_Norm.Z > 0.0f ? bounds[1].Z : bounds[0].Z;
farPoint.X = m_Planes[i].m_Norm.X > 0.0f ? bounds[1].X : bounds[0].X;
farPoint.Y = m_Planes[i].m_Norm.Y > 0.0f ? bounds[1].Y : bounds[0].Y;
farPoint.Z = m_Planes[i].m_Norm.Z > 0.0f ? bounds[1].Z : bounds[0].Z;
if (m_aPlanes[i].IsPointOnBackSide(FarPoint))
if (m_Planes[i].IsPointOnBackSide(farPoint))
return false;
}
+16 -21
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2009 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -30,46 +30,41 @@ portal rendering, where a portal may have 3 or more edges.
#include "maths/Plane.h"
//10 planes should be enough
#define MAX_NUM_FRUSTUM_PLANES (10)
class CBoundingBoxAligned;
class CMatrix3D;
class CFrustum
{
public:
CFrustum ();
~CFrustum ();
CFrustum();
~CFrustum();
//Set the number of planes to use for
//calculations. This is clipped to
//[0,MAX_NUM_FRUSTUM_PLANES]
void SetNumPlanes (size_t num);
// Set the number of planes to use for calculations. This is clamped to
// [0, MAX_NUM_FRUSTUM_PLANES].
void SetNumPlanes(size_t num);
size_t GetNumPlanes() const { return m_NumPlanes; }
void AddPlane (const CPlane& plane);
void AddPlane(const CPlane& plane);
void Transform(CMatrix3D& m);
void Transform(const CMatrix3D& m);
//The following methods return true if the shape is
//partially or completely in front of the frustum planes
// The following methods return true if the shape is
// partially or completely in front of the frustum planes.
bool IsPointVisible(const CVector3D& point) const;
bool DoesSegmentIntersect(const CVector3D& start, const CVector3D& end) const;
bool IsSphereVisible(const CVector3D& center, float radius) const;
bool IsBoxVisible(const CVector3D& position, const CBoundingBoxAligned& bounds) const;
bool IsBoxVisible(const CBoundingBoxAligned& bounds) const;
CPlane& operator[](size_t idx) { return m_aPlanes[idx]; }
const CPlane& operator[](size_t idx) const { return m_aPlanes[idx]; }
public:
//make the planes public for ease of use
CPlane m_aPlanes[MAX_NUM_FRUSTUM_PLANES];
CPlane& operator[](size_t idx) { return m_Planes[idx]; }
const CPlane& operator[](size_t idx) const { return m_Planes[idx]; }
private:
static const size_t MAX_NUM_FRUSTUM_PLANES = 10;
CPlane m_Planes[MAX_NUM_FRUSTUM_PLANES];
size_t m_NumPlanes;
};
#endif
#endif // INCLUDED_FRUSTUM
+13 -13
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -233,28 +233,28 @@ CFrustum CBoundingBoxAligned::ToFrustum() const
frustum.SetNumPlanes(6);
// get the LEFT plane
frustum.m_aPlanes[0].m_Norm = CVector3D(1, 0, 0);
frustum.m_aPlanes[0].m_Dist = -m_Data[0].X;
frustum[0].m_Norm = CVector3D(1, 0, 0);
frustum[0].m_Dist = -m_Data[0].X;
// get the RIGHT plane
frustum.m_aPlanes[1].m_Norm = CVector3D(-1, 0, 0);
frustum.m_aPlanes[1].m_Dist = m_Data[1].X;
frustum[1].m_Norm = CVector3D(-1, 0, 0);
frustum[1].m_Dist = m_Data[1].X;
// get the BOTTOM plane
frustum.m_aPlanes[2].m_Norm = CVector3D(0, 1, 0);
frustum.m_aPlanes[2].m_Dist = -m_Data[0].Y;
frustum[2].m_Norm = CVector3D(0, 1, 0);
frustum[2].m_Dist = -m_Data[0].Y;
// get the TOP plane
frustum.m_aPlanes[3].m_Norm = CVector3D(0, -1, 0);
frustum.m_aPlanes[3].m_Dist = m_Data[1].Y;
frustum[3].m_Norm = CVector3D(0, -1, 0);
frustum[3].m_Dist = m_Data[1].Y;
// get the NEAR plane
frustum.m_aPlanes[4].m_Norm = CVector3D(0, 0, 1);
frustum.m_aPlanes[4].m_Dist = -m_Data[0].Z;
frustum[4].m_Norm = CVector3D(0, 0, 1);
frustum[4].m_Dist = -m_Data[0].Z;
// get the FAR plane
frustum.m_aPlanes[5].m_Norm = CVector3D(0, 0, -1);
frustum.m_aPlanes[5].m_Dist = m_Data[1].Z;
frustum[5].m_Norm = CVector3D(0, 0, -1);
frustum[5].m_Dist = m_Data[1].Z;
return frustum;
}