diff --git a/modules/scene/include/vkcv/scene/Bounds.hpp b/modules/scene/include/vkcv/scene/Bounds.hpp index 2ab081c1f42c221239e4b0c724e41968e561b50f..8ad5806506610dbef6e4f1e0e26d66dfe0dbb63b 100644 --- a/modules/scene/include/vkcv/scene/Bounds.hpp +++ b/modules/scene/include/vkcv/scene/Bounds.hpp @@ -32,6 +32,13 @@ namespace vkcv::scene { * box. */ Bounds(); + + /** + * Constructor creating a zero volume axis aligned bounding + * box around a certain point. + * @param[in] point Center of the box as 3D vector + */ + Bounds(const glm::vec3& point); /** * Constructor creating an axis aligned bounding box with given diff --git a/modules/scene/include/vkcv/scene/Frustum.hpp b/modules/scene/include/vkcv/scene/Frustum.hpp index 040f53b950eeb484ab1f4736bfa250fbf368fb89..e40092240614a5ee76fe3f5aa5a43db98d39970a 100644 --- a/modules/scene/include/vkcv/scene/Frustum.hpp +++ b/modules/scene/include/vkcv/scene/Frustum.hpp @@ -9,6 +9,16 @@ namespace vkcv::scene { * @addtogroup vkcv_scene * @{ */ + + /** + * Transform a given axis aligned bounding box into frustum coordinates + * using a given 4x4 transformation matrix to return a new axis aligned + * bounding box containing that transformed box. + * @param[in] transform Frustum defining 4x4 matrix + * @param[in] bounds Axis aligned bounding box + * @return Bounds containing box in frustum coordinates + */ + Bounds transformBounds(const glm::mat4& transform, const Bounds& bounds); /** * Transform a given axis aligned bounding box into frustum coordinates @@ -16,10 +26,10 @@ namespace vkcv::scene { * bounding box containing that transformed box. * @param[in] transform Frustum defining 4x4 matrix * @param[in] bounds Axis aligned bounding box - * @param[out] negative_w Flag if w-coordinate is negative (optional) + * @param[out] negative_w Flag if w-coordinate is negative * @return Bounds containing box in frustum coordinates */ - Bounds transformBounds(const glm::mat4& transform, const Bounds& bounds, bool* negative_w = nullptr); + Bounds transformBounds(const glm::mat4& transform, const Bounds& bounds, bool& negative_w); /** * Check if an axis aligned bounding box is intersecting a given frustum diff --git a/modules/scene/src/vkcv/scene/Bounds.cpp b/modules/scene/src/vkcv/scene/Bounds.cpp index 731d81e928deae4c27f5c857de5b94dc3180888b..9614208d2d523117eef09e1432ff755005b5c51f 100644 --- a/modules/scene/src/vkcv/scene/Bounds.cpp +++ b/modules/scene/src/vkcv/scene/Bounds.cpp @@ -7,6 +7,11 @@ namespace vkcv::scene { m_min(glm::vec3(0)), m_max(glm::vec3(0)) {} + Bounds::Bounds(const glm::vec3 &point) : + m_min(point), + m_max(point) + {} + Bounds::Bounds(const glm::vec3 &min, const glm::vec3 &max) : m_min(min), m_max(max) diff --git a/modules/scene/src/vkcv/scene/Frustum.cpp b/modules/scene/src/vkcv/scene/Frustum.cpp index 1f63eb1d07002d24add81872627777048642dcdb..10af3bc44e4f585f990577bd9d95ecfade7acca8 100644 --- a/modules/scene/src/vkcv/scene/Frustum.cpp +++ b/modules/scene/src/vkcv/scene/Frustum.cpp @@ -3,10 +3,9 @@ namespace vkcv::scene { - static glm::vec3 transformPoint(const glm::mat4& transform, const glm::vec3& point, bool* negative_w) { + static glm::vec3 transformPoint(const glm::mat4& transform, const glm::vec3& point, bool& negative_w) { const glm::vec4 position = transform * glm::vec4(point, 1.0f); - /* * We divide by the absolute of the 4th coorditnate because * clipping is weird and points have to move to the other @@ -16,39 +15,35 @@ namespace vkcv::scene { * to know if all corners are behind the camera. So these can * be culled as well */ - if (negative_w) { - const float perspective = std::abs(position[3]); - - *negative_w &= (position[3] < 0.0f); - - return glm::vec3( - position[0] / perspective, - position[1] / perspective, - position[2] / perspective - ); - } else { - return glm::vec3( - position[0], - position[1], - position[2] - ); - } + const float perspective = std::abs(position[3]); + negative_w &= (position[3] < 0.0f); + return glm::vec3( + position[0] / perspective, + position[1] / perspective, + position[2] / perspective + ); } - Bounds transformBounds(const glm::mat4& transform, const Bounds& bounds, bool* negative_w) { + Bounds transformBounds(const glm::mat4& transform, const Bounds& bounds) { const auto corners = bounds.getCorners(); - if (negative_w) { - *negative_w = true; + Bounds result (glm::vec3(transform * glm::vec4(corners[0], 1.0f))); + + for (size_t j = 1; j < corners.size(); j++) { + result.extend(glm::vec3(transform * glm::vec4(corners[j], 1.0f))); } - auto projected = transformPoint(transform, corners[0], negative_w); + return result; + } + + Bounds transformBounds(const glm::mat4& transform, const Bounds& bounds, bool& negative_w) { + const auto corners = bounds.getCorners(); + negative_w = true; - Bounds result (projected, projected); + Bounds result (transformPoint(transform, corners[0], negative_w)); for (size_t j = 1; j < corners.size(); j++) { - projected = transformPoint(transform, corners[j], negative_w); - result.extend(projected); + result.extend(transformPoint(transform, corners[j], negative_w)); } return result; @@ -61,7 +56,7 @@ namespace vkcv::scene { ); bool negative_w; - auto box = transformBounds(transform, bounds, &negative_w); + auto box = transformBounds(transform, bounds, negative_w); if (negative_w) { return false;