Renderer/DebugDrawer: Add support for Frustum
This commit is contained in:
parent
f572d229d9
commit
a5d4b8f28d
|
|
@ -32,6 +32,8 @@ namespace Nz
|
|||
Frustum(const Frustum& frustum) = default;
|
||||
~Frustum() = default;
|
||||
|
||||
Vector3<T> ComputeCorner(BoxCorner corner) const;
|
||||
|
||||
bool Contains(const BoundingVolume<T>& volume) const;
|
||||
bool Contains(const Box<T>& box) const;
|
||||
bool Contains(const OrientedBox<T>& orientedBox) const;
|
||||
|
|
@ -47,8 +49,6 @@ namespace Nz
|
|||
IntersectionSide Intersect(const Sphere<T>& sphere) const;
|
||||
IntersectionSide Intersect(const Vector3<T>* points, std::size_t pointCount) const;
|
||||
|
||||
template<typename U> Frustum& Set(const Frustum<U>& frustum);
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
Frustum& operator=(const Frustum& other) = default;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,31 @@ namespace Nz
|
|||
m_planes[i].Set(frustum.m_planes[i]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the position of a frustum corner
|
||||
* \return The corner position
|
||||
*
|
||||
* \param corner Which corner to compute
|
||||
*/
|
||||
template<typename T>
|
||||
Vector3<T> Frustum<T>::ComputeCorner(BoxCorner corner) const
|
||||
{
|
||||
switch (corner)
|
||||
{
|
||||
case BoxCorner::FarLeftBottom: return Plane<T>::Intersect(GetPlane(FrustumPlane::Far), GetPlane(FrustumPlane::Left), GetPlane(FrustumPlane::Bottom));
|
||||
case BoxCorner::FarLeftTop: return Plane<T>::Intersect(GetPlane(FrustumPlane::Far), GetPlane(FrustumPlane::Left), GetPlane(FrustumPlane::Top));
|
||||
case BoxCorner::FarRightBottom: return Plane<T>::Intersect(GetPlane(FrustumPlane::Far), GetPlane(FrustumPlane::Right), GetPlane(FrustumPlane::Bottom));
|
||||
case BoxCorner::FarRightTop: return Plane<T>::Intersect(GetPlane(FrustumPlane::Far), GetPlane(FrustumPlane::Right), GetPlane(FrustumPlane::Top));
|
||||
case BoxCorner::NearLeftBottom: return Plane<T>::Intersect(GetPlane(FrustumPlane::Near), GetPlane(FrustumPlane::Left), GetPlane(FrustumPlane::Bottom));
|
||||
case BoxCorner::NearLeftTop: return Plane<T>::Intersect(GetPlane(FrustumPlane::Near), GetPlane(FrustumPlane::Left), GetPlane(FrustumPlane::Top));
|
||||
case BoxCorner::NearRightBottom: return Plane<T>::Intersect(GetPlane(FrustumPlane::Near), GetPlane(FrustumPlane::Right), GetPlane(FrustumPlane::Bottom));
|
||||
case BoxCorner::NearRightTop: return Plane<T>::Intersect(GetPlane(FrustumPlane::Near), GetPlane(FrustumPlane::Right), GetPlane(FrustumPlane::Top));
|
||||
}
|
||||
|
||||
NazaraError("invalid frustum corner");
|
||||
return Vector3<T>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not a bounding volume is contained in the frustum
|
||||
* \return true if the bounding volume is entirely in the frustum
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ namespace Nz
|
|||
bool operator==(const Plane& plane) const;
|
||||
bool operator!=(const Plane& plane) const;
|
||||
|
||||
static Vector3<T> Intersect(const Plane& p0, const Plane& p1, const Plane& p2);
|
||||
static Plane Lerp(const Plane& from, const Plane& to, T interpolation);
|
||||
static Plane XY();
|
||||
static Plane XZ();
|
||||
|
|
|
|||
|
|
@ -330,6 +330,28 @@ namespace Nz
|
|||
return !operator==(plane);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Intersects three planes to retrieve a single intersection point
|
||||
* \return The intersection point
|
||||
*
|
||||
* \param p0 First plane
|
||||
* \param p1 Second plane
|
||||
* \param p2 Third plane
|
||||
*
|
||||
* \remark All three planes must have differents normals otherwise result is undefined
|
||||
*/
|
||||
template<typename T>
|
||||
Vector3<T> Plane<T>::Intersect(const Plane& p0, const Plane& p1, const Plane& p2)
|
||||
{
|
||||
// From https://donw.io/post/frustum-point-extraction/
|
||||
Vector3f bxc = Vector3f::CrossProduct(p1.normal, p2.normal);
|
||||
Vector3f cxa = Vector3f::CrossProduct(p2.normal, p0.normal);
|
||||
Vector3f axb = Vector3f::CrossProduct(p0.normal, p1.normal);
|
||||
Vector3f r = -p0.distance * bxc - p1.distance * cxa - p2.distance * axb;
|
||||
|
||||
return r * (T(1.0) / Vector3f::DotProduct(p0.normal, bxc));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the plane to other one with a factor of interpolation
|
||||
* \return A new plane which is the interpolation of two planes
|
||||
|
|
@ -343,7 +365,6 @@ namespace Nz
|
|||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
Plane<T> Plane<T>::Lerp(const Plane& from, const Plane& to, T interpolation)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Math/Box.hpp>
|
||||
#include <Nazara/Math/Frustum.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
|
|
@ -40,6 +41,7 @@ namespace Nz
|
|||
void Draw(CommandBufferBuilder& builder);
|
||||
|
||||
inline void DrawBox(const Boxf& box, const Color& color);
|
||||
inline void DrawFrustum(const Frustumf& frustum, const Color& color);
|
||||
inline void DrawLine(const Vector3f& start, const Vector3f& end, const Color& color);
|
||||
inline void DrawLine(const Vector3f& start, const Vector3f& end, const Color& startColor, const Color& endColor);
|
||||
void DrawSkeleton(const Skeleton& skeleton, const Color& color);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,26 @@ namespace Nz
|
|||
DrawLine({ max.x, min.y, min.z }, { max.x, min.y, max.z }, color);
|
||||
}
|
||||
|
||||
inline void DebugDrawer::DrawFrustum(const Frustumf& frustum, const Color& color)
|
||||
{
|
||||
std::array<Vector3f, BoxCornerCount> corners;
|
||||
for (std::size_t i = 0; i < BoxCornerCount; ++i)
|
||||
corners[i] = frustum.ComputeCorner(static_cast<BoxCorner>(i));
|
||||
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearLeftBottom)], corners[UnderlyingCast(BoxCorner::NearRightBottom)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearLeftBottom)], corners[UnderlyingCast(BoxCorner::NearLeftTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearLeftBottom)], corners[UnderlyingCast(BoxCorner::FarLeftBottom)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::FarRightTop)], corners[UnderlyingCast(BoxCorner::FarLeftTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::FarRightTop)], corners[UnderlyingCast(BoxCorner::FarRightBottom)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::FarRightTop)], corners[UnderlyingCast(BoxCorner::NearRightTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::FarLeftBottom)], corners[UnderlyingCast(BoxCorner::FarRightBottom)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::FarLeftBottom)], corners[UnderlyingCast(BoxCorner::FarLeftTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearLeftTop)], corners[UnderlyingCast(BoxCorner::NearRightTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearLeftTop)], corners[UnderlyingCast(BoxCorner::FarLeftTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearRightBottom)], corners[UnderlyingCast(BoxCorner::NearRightTop)], color);
|
||||
DrawLine(corners[UnderlyingCast(BoxCorner::NearRightBottom)], corners[UnderlyingCast(BoxCorner::FarRightBottom)], color);
|
||||
}
|
||||
|
||||
inline void DebugDrawer::DrawLine(const Vector3f& start, const Vector3f& end, const Color& color)
|
||||
{
|
||||
return DrawLine(start, end, color, color);
|
||||
|
|
|
|||
Loading…
Reference in New Issue