58 lines
2.2 KiB
C++
58 lines
2.2 KiB
C++
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
|
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <Jolt/Geometry/Plane.h>
|
|
#include <Jolt/Geometry/AABox.h>
|
|
|
|
/// A camera frustum containing of 6 planes (left, right, top, bottom, near, far) pointing inwards
|
|
class [[nodiscard]] Frustum
|
|
{
|
|
public:
|
|
/// Empty constructor
|
|
Frustum() = default;
|
|
|
|
/// Construct frustum from position, forward, up, field of view x and y and near plane.
|
|
/// Note that inUp does not need to be perpendicular to inForward but cannot be collinear.
|
|
inline Frustum(Vec3Arg inPosition, Vec3Arg inForward, Vec3Arg inUp, float inFOVX, float inFOVY, float inNear)
|
|
{
|
|
Vec3 right = inForward.Cross(inUp).Normalized();
|
|
Vec3 up = right.Cross(inForward).Normalized(); // Calculate the real up vector (inUp does not need to be perpendicular to inForward)
|
|
|
|
// Near plane
|
|
mPlanes[0] = Plane::sFromPointAndNormal(inPosition + inNear * inForward, inForward);
|
|
|
|
// Top and bottom planes
|
|
mPlanes[1] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, 0.5f * inFOVY) * -up);
|
|
mPlanes[2] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, -0.5f * inFOVY) * up);
|
|
|
|
// Left and right planes
|
|
mPlanes[3] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, 0.5f * inFOVX) * right);
|
|
mPlanes[4] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, -0.5f * inFOVX) * -right);
|
|
}
|
|
|
|
/// Test if frustum overlaps with axis aligned box. Note that this is a conservative estimate and can return true if the
|
|
/// frustum doesn't actually overlap with the box. This is because we only test the plane axis as separating axis
|
|
/// and skip checking the cross products of the edges of the frustum
|
|
inline bool Overlaps(const AABox &inBox) const
|
|
{
|
|
// Loop over all frustum planes
|
|
for (const Plane &p : mPlanes)
|
|
{
|
|
// Get support point (the maximum extent) in the direction of our normal
|
|
Vec3 support = inBox.GetSupport(p.GetNormal());
|
|
|
|
// If this is behind our plane, the box is not inside the frustum
|
|
if (p.SignedDistance(support) < 0.0f)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
Plane mPlanes[5]; ///< Planes forming the frustum
|
|
};
|