You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

220 lines
6.0 KiB

// David Eberly, Geometric Tools, Redmond WA 98052
// Copyright (c) 1998-2021
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
// https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
// Version: 4.0.2019.08.13
#pragma once
#include <Mathematics/Vector3.h>
// Orthogonal frustum. Let E be the origin, D be the direction vector, U be
// the up vector, and R be the right vector. Let u > 0 and r > 0 be the
// extents in the U and R directions, respectively. Let n and f be the
// extents in the D direction with 0 < n < f. The four corners of the frustum
// in the near plane are E + n*D + s0*u*U + s1*r*R where |s0| = |s1| = 1 (four
// choices). The four corners of the frustum in the far plane are
// E + f*D + (f/n)*(s0*u*U + s1*r*R) where |s0| = |s1| = 1 (four choices).
namespace gte
{
template <typename Real>
class Frustum3
{
public:
// Construction and destruction. The default constructor sets the
// following values: origin (E) to (0,0,0), dVector (D) to (0,0,1),
// uVector (U) to (0,1,0), rVector (R) to (1,0,0), dMin (n) to 1,
// dMax (f) to 2, uBound (u) to 1, and rBound (r) to 1.
Frustum3()
:
origin(Vector3<Real>::Zero()),
dVector(Vector3<Real>::Unit(2)),
uVector(Vector3<Real>::Unit(1)),
rVector(Vector3<Real>::Unit(0)),
dMin((Real)1),
dMax((Real)2),
uBound((Real)1),
rBound((Real)1)
{
Update();
}
Frustum3(Vector3<Real> const& inOrigin, Vector3<Real> const& inDVector,
Vector3<Real> const& inUVector, Vector3<Real> const& inRVector,
Real inDMin, Real inDMax, Real inUBound, Real inRBound)
:
origin(inOrigin),
dVector(inDVector),
uVector(inUVector),
rVector(inRVector),
dMin(inDMin),
dMax(inDMax),
uBound(inUBound),
rBound(inRBound)
{
Update();
}
// The Update() function must be called whenever changes are made to
// dMin, dMax, uBound or rBound. The values mDRatio, mMTwoUF and
// mMTwoRF are dependent on the changes, so call the Get*() accessors
// only after the Update() call.
void Update()
{
mDRatio = dMax / dMin;
mMTwoUF = (Real)-2 * uBound * dMax;
mMTwoRF = (Real)-2 * rBound * dMax;
}
inline Real GetDRatio() const
{
return mDRatio;
}
inline Real GetMTwoUF() const
{
return mMTwoUF;
}
inline Real GetMTwoRF() const
{
return mMTwoRF;
}
void ComputeVertices(std::array<Vector3<Real>, 8>& vertex) const
{
Vector3<Real> dScaled = dMin * dVector;
Vector3<Real> uScaled = uBound * uVector;
Vector3<Real> rScaled = rBound * rVector;
vertex[0] = dScaled - uScaled - rScaled;
vertex[1] = dScaled - uScaled + rScaled;
vertex[2] = dScaled + uScaled + rScaled;
vertex[3] = dScaled + uScaled - rScaled;
for (int i = 0, ip = 4; i < 4; ++i, ++ip)
{
vertex[ip] = origin + mDRatio * vertex[i];
vertex[i] += origin;
}
}
Vector3<Real> origin, dVector, uVector, rVector;
Real dMin, dMax, uBound, rBound;
public:
// Comparisons to support sorted containers.
bool operator==(Frustum3 const& frustum) const
{
return origin == frustum.origin
&& dVector == frustum.dVector
&& uVector == frustum.uVector
&& rVector == frustum.rVector
&& dMin == frustum.dMin
&& dMax == frustum.dMax
&& uBound == frustum.uBound
&& rBound == frustum.rBound;
}
bool operator!=(Frustum3 const& frustum) const
{
return !operator==(frustum);
}
bool operator< (Frustum3 const& frustum) const
{
if (origin < frustum.origin)
{
return true;
}
if (origin > frustum.origin)
{
return false;
}
if (dVector < frustum.dVector)
{
return true;
}
if (dVector > frustum.dVector)
{
return false;
}
if (uVector < frustum.uVector)
{
return true;
}
if (uVector > frustum.uVector)
{
return false;
}
if (rVector < frustum.rVector)
{
return true;
}
if (rVector > frustum.rVector)
{
return false;
}
if (dMin < frustum.dMin)
{
return true;
}
if (dMin > frustum.dMin)
{
return false;
}
if (dMax < frustum.dMax)
{
return true;
}
if (dMax > frustum.dMax)
{
return false;
}
if (uBound < frustum.uBound)
{
return true;
}
if (uBound > frustum.uBound)
{
return false;
}
return rBound < frustum.rBound;
}
bool operator<=(Frustum3 const& frustum) const
{
return !frustum.operator<(*this);
}
bool operator> (Frustum3 const& frustum) const
{
return frustum.operator<(*this);
}
bool operator>=(Frustum3 const& frustum) const
{
return !operator<(frustum);
}
protected:
// Quantities derived from the constructor inputs.
Real mDRatio, mMTwoUF, mMTwoRF;
};
}