forked from mirrors/0ad
Cleanups Frustum and removes access to members.
This was SVN commit r25158.
This commit is contained in:
+25
-25
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user