12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- // 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 frustom from position, forward, up, field of view x and y and near and far 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, float inFar)
- {
- 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 and far plane
- mPlanes[0] = Plane::sFromPointAndNormal(inPosition + inNear * inForward, inForward);
- mPlanes[1] = Plane::sFromPointAndNormal(inPosition + inFar * inForward, -inForward);
- // Top and bottom planes
- mPlanes[2] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, 0.5f * inFOVY) * -up);
- mPlanes[3] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, -0.5f * inFOVY) * up);
- // Left and right planes
- mPlanes[4] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, 0.5f * inFOVX) * right);
- mPlanes[5] = 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[6]; ///< Planes forming the frustum
- };
|