diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2026-02-15 00:50:02 +0000 |
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2026-02-15 00:50:02 +0000 |
| commit | 8496bd9720888701267f8f39a2f3a74a65f1006f (patch) | |
| tree | 6f902b6302f9573cd7f45f9b1d6255d4ae024432 /gfx | |
| parent | Refactor test-instancing so the data is generated in a common fixture (diff) | |
| download | ilt-8496bd9720888701267f8f39a2f3a74a65f1006f.tar.bz2 ilt-8496bd9720888701267f8f39a2f3a74a65f1006f.tar.xz ilt-8496bd9720888701267f8f39a2f3a74a65f1006f.zip | |
Support for testing if a point/sphere is within a Frustum
Use case is the sphere approximating a scenery item such as a tree.
Diffstat (limited to 'gfx')
| -rw-r--r-- | gfx/frustum.cpp | 24 | ||||
| -rw-r--r-- | gfx/frustum.h | 4 |
2 files changed, 25 insertions, 3 deletions
diff --git a/gfx/frustum.cpp b/gfx/frustum.cpp index faa676d..5c85ac0 100644 --- a/gfx/frustum.cpp +++ b/gfx/frustum.cpp @@ -48,9 +48,27 @@ Frustum::boundByPlanes(const BoundingBox & aabb, size_t nplanes) const = 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(std::span(planes).subspan(0, nplanes), [&corners](const auto & frustumPlane) { - return (std::ranges::all_of(corners, [&frustumPlane](const auto & corner) { - return glm::dot(frustumPlane, corner) < 0.F; + return contains(corners, nplanes, 0); +} + +bool +Frustum::contains(GlobalPosition3D point, RelativeDistance size) const +{ + return contains(std::array {RelativePosition4D {(point - position), 1.F}}, FACES, size); +} + +bool +Frustum::shadedBy(GlobalPosition3D point, RelativeDistance size) const +{ + return contains(std::array {RelativePosition4D {(point - position), 1.F}}, FACES - 1, size); +} + +bool +Frustum::contains(const std::span<const RelativePosition4D> points, const size_t nplanes, RelativeDistance size) const +{ + return std::ranges::none_of(std::span(planes).subspan(0, nplanes), [&points, size](const auto & frustumPlane) { + return (std::ranges::all_of(points, [&frustumPlane, size](const auto & corner) { + return glm::dot(frustumPlane, corner) < -size; })); }); } diff --git a/gfx/frustum.h b/gfx/frustum.h index a2d90e9..1493a36 100644 --- a/gfx/frustum.h +++ b/gfx/frustum.h @@ -4,6 +4,7 @@ #include "config/types.h" #include <array> #include <glm/mat4x4.hpp> +#include <span> class Frustum { public: @@ -31,12 +32,15 @@ public: using BoundingBox = AxisAlignedBoundingBox<GlobalDistance>; [[nodiscard]] bool contains(const BoundingBox &) const; + [[nodiscard]] bool contains(GlobalPosition3D, RelativeDistance size = 0) const; [[nodiscard]] bool shadedBy(const BoundingBox &) const; + [[nodiscard]] bool shadedBy(GlobalPosition3D, RelativeDistance size = 0) const; protected: static constexpr size_t FACES = 6; void updateCache(); [[nodiscard]] bool boundByPlanes(const BoundingBox &, size_t nplanes) const; + [[nodiscard]] bool contains(std::span<const RelativePosition4D>, size_t nplanes, RelativeDistance) const; GlobalPosition3D position; glm::mat4 view, projection; |
