From d0aceb54752078200bc75a96888ffaf7483678cb Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 7 Mar 2025 00:43:25 +0000 Subject: Add function to test if an AABB is visible in a frustum --- gfx/frustum.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'gfx/frustum.cpp') diff --git a/gfx/frustum.cpp b/gfx/frustum.cpp index a9dbdf0..8031d85 100644 --- a/gfx/frustum.cpp +++ b/gfx/frustum.cpp @@ -1,4 +1,5 @@ #include "frustum.h" +#include "aabb.h" #include #include #include @@ -18,6 +19,31 @@ Frustum::updateView(const glm::mat4 & newView) updateCache(); } +bool +Frustum::contains(const AxisAlignedBoundingBox & aabb) const +{ + static constexpr auto EXTENT_CORNER_IDXS = [] { + using Extent = GlobalPosition3D AxisAlignedBoundingBox::*; + constexpr auto EXTENTS = std::array {&AxisAlignedBoundingBox::min, &AxisAlignedBoundingBox::max}; + std::array, 2ZU * 2ZU * 2ZU> out {}; + std::ranges::copy(std::views::cartesian_product(EXTENTS, EXTENTS, EXTENTS) + | std::views::transform( + std::make_from_tuple, std::tuple>), + out.begin()); + return out; + }(); + + const std::array corners + = EXTENT_CORNER_IDXS * [relativeAabb = aabb - position](auto idxs) -> glm::vec4 { + return {(relativeAabb.*(idxs.x)).x, (relativeAabb.*(idxs.y)).y, (relativeAabb.*(idxs.z)).z, 1.F}; + }; + return std::ranges::none_of(planes, [&corners](const auto & frustumPlane) { + return (std::ranges::all_of(corners, [&frustumPlane](const auto & corner) { + return glm::dot(frustumPlane, corner) < 0.F; + })); + }); +} + void Frustum::updateCache() { -- cgit v1.2.3