From 7ef6503a78e830c42ef00c4bef7453fd51769dbf Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 00:28:10 +0100 Subject: [PATCH] Add 2d variant of bounding box --- openVulkanoCpp/Math/AABB.hpp | 79 ++++++++++--------- .../Scene/Prefabs/LabelDrawable.hpp | 4 +- openVulkanoCpp/Scene/Ray.cpp | 64 +++++++-------- openVulkanoCpp/Scene/Ray.hpp | 20 ++++- openVulkanoCpp/Scene/TextDrawable.hpp | 4 +- 5 files changed, 92 insertions(+), 79 deletions(-) diff --git a/openVulkanoCpp/Math/AABB.hpp b/openVulkanoCpp/Math/AABB.hpp index 5c0039b..d0b8b3b 100644 --- a/openVulkanoCpp/Math/AABB.hpp +++ b/openVulkanoCpp/Math/AABB.hpp @@ -14,101 +14,103 @@ namespace OpenVulkano::Math /** * \brief A class that represents an axis aligned bounding box */ - class AABB final : public Range + template + class AABB_T final : public Range { public: - AABB() : Range(Vector3f(INFINITY), Vector3f(-INFINITY)) {} + AABB_T() : Range(T(INFINITY), T(-INFINITY)) {} - AABB(const Vector3f& min, const Vector3f& max) : Range(min, max) {} + AABB_T(const T& min, const T& max) : Range(min, max) {} - AABB(const Vector3f& point) : Range(point, point) + AABB_T(const T& point) : Range(point, point) {} - AABB(const Vector3f& point, float radius) : Range(point - radius, point + radius) + AABB_T(const T& point, float radius) : Range(point - radius, point + radius) {} /** * \brief Initiates the AABB to a single point (min=max=point) * \param point The point that should be used as min and max of the AABB */ - void Init(const Vector3f& point) + void Init(const T& point) { - min = max = point; + Range::min = Range::max = point; } - void Init(const Vector3f& min, const Vector3f& max) + void Init(const T& min, const T& max) { this->min = min; this->max = max; } - void Init(const Vector3f& point, float radius) + void Init(const T& point, float radius) { - min = point - radius; - max = point + radius; + Range::min = point - radius; + Range::max = point + radius; } /** * \brief Initiates the AABB from some other AABB * \param other The other AABB that should be copied */ - void Init(const AABB& other) + void Init(const AABB_T& other) { - min = other.GetMin(); - max = other.GetMax(); + Range::min = other.GetMin(); + Range::max = other.GetMax(); } - void Grow(const Vector3f& point) + void Grow(const T& point) { - min = Math::Utils::min(min, point); - max = Math::Utils::max(max, point); + Range::min = Math::Utils::min(Range::min, point); + Range::max = Math::Utils::max(Range::max, point); } - void Grow(const AABB& otherAABB) + void Grow(const AABB_T& otherAABB) { - min = Math::Utils::min(min, otherAABB.GetMin()); - max = Math::Utils::max(max, otherAABB.GetMax()); + Range::min = Math::Utils::min(Range::min, otherAABB.GetMin()); + Range::max = Math::Utils::max(Range::max, otherAABB.GetMax()); } - void Grow(const AABB& otherAABB, Math::Matrix4f transformation) + void Grow(const AABB_T& otherAABB, Math::Matrix4f transformation) { //TODO } - [[nodiscard]] Vector3f GetDiagonal() const + [[nodiscard]] T GetDiagonal() const { - return GetSize(); + return Range::GetSize(); } - [[nodiscard]] Vector3f GetCenter() const + [[nodiscard]] T GetCenter() const { - return min + (GetDiagonal() * 0.5f); + return Range::min + (GetDiagonal() * 0.5f); } /** - * \brief Checks if the AABB overlaps with an other AABB + * \brief Checks if the AABB overlaps with another AABB * \param other The other AABB that should be checked * \return true if the AABB overlaps with the other, false if not */ - [[nodiscard]] bool IsOverlapping(const AABB& other) const + [[nodiscard]] bool IsOverlapping(const AABB_T& other) const { - return !(other.min.x > max.x || other.max.x < min.x || other.min.y > max.y || - other.max.y < min.y || other.min.z > max.z || other.max.z < min.z); + //return !(other.min.x > max.x || other.max.x < min.x || other.min.y > max.y || + // other.max.y < min.y || other.min.z > max.z || other.max.z < min.z); + return Math::Utils::any(Math::Utils::greaterThan(Range::min, other.GetMin())) || Math::Utils::any(Math::Utils::lessThan(other.GetMax(), Range::max)); } - [[nodiscard]] bool InBounds(const Vector3f& position) const + [[nodiscard]] bool InBounds(const T& position) const { - return Math::Utils::all(Math::Utils::lessThanEqual(min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, max)); + return Math::Utils::all(Math::Utils::lessThanEqual(Range::min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, Range::max)); } - [[nodiscard]] bool Inside(const Math::Vector3f& position) const + [[nodiscard]] bool Inside(const T& position) const { - return Math::Utils::all(Math::Utils::lessThan(min, position)) && Math::Utils::all(Math::Utils::lessThan(position, max)); + return Math::Utils::all(Math::Utils::lessThan(Range::min, position)) && Math::Utils::all(Math::Utils::lessThan(position, Range::max)); } [[nodiscard]] bool IsEmpty() const { - return min == Math::Vector3f(INFINITY) && max == Math::Vector3f(-INFINITY); + return Range::min == T(INFINITY) && Range::max == T(-INFINITY); } /** @@ -116,10 +118,13 @@ namespace OpenVulkano::Math */ void Reset() { - min = Vector3f(INFINITY); - max = Vector3f(-INFINITY); + Range::min = T(INFINITY); + Range::max = T(-INFINITY); } - AABB& operator +=(const AABB& other) { Grow(other); return *this; } + AABB_T& operator +=(const AABB_T& other) { Grow(other); return *this; } }; + + typedef AABB_T AABB; + typedef AABB_T AABB2f; } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 7458d00..e50ec50 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -53,7 +53,7 @@ namespace OpenVulkano::Scene [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } [[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; } - [[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; } + [[nodiscard]] const Math::AABB2f& GetBoundingBox() const { return m_bbox; } std::optional Intersect(const Ray& ray) const override; private: @@ -63,6 +63,6 @@ namespace OpenVulkano::Scene LabelDrawableSettings m_settings; LabelUniformData m_labelData; Math::Vector3f m_position = { 0, 0, 0 }; - Math::AABB m_bbox; + Math::AABB2f m_bbox; }; } diff --git a/openVulkanoCpp/Scene/Ray.cpp b/openVulkanoCpp/Scene/Ray.cpp index 7e2a30c..ec09810 100644 --- a/openVulkanoCpp/Scene/Ray.cpp +++ b/openVulkanoCpp/Scene/Ray.cpp @@ -92,6 +92,12 @@ namespace OpenVulkano::Scene return {}; } + std::optional Ray::IntersectAABB(const Math::AABB2f& bbox) const + { + //TODO impl that skips z checks + return IntersectAABB(Math::AABB({bbox.GetMin(), 0}, {bbox.GetMax(), 0})); + } + std::optional Ray::IntersectAABB(const Math::AABB& bbox) const { RayHit h1, h2; @@ -108,69 +114,63 @@ namespace OpenVulkano::Scene int Ray::IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const { - const auto tmin = (bbox.min - m_origin) / m_dir; - const auto tmax = (bbox.max - m_origin) / m_dir; - float txmin = tmin.x; - float txmax = tmax.x; - float tymin = tmin.y; - float tymax = tmax.y; - float tzmin = tmin.z; - float tzmax = tmax.z; + auto tmin = (bbox.min - m_origin) / m_dir; + auto tmax = (bbox.max - m_origin) / m_dir; - if (txmin > txmax) + if (tmin.x > tmax.x) { - std::swap(txmin, txmax); + std::swap(tmin.x, tmax.x); } - if (tymin > tymax) + if (tmin.y > tmax.y) { - std::swap(tymin, tymax); + std::swap(tmin.y, tmax.y); } - if ((txmin > tymax) || (tymin > txmax)) + if ((tmin.x > tmax.y) || (tmin.y > tmax.x)) { return 0; } - if (tymin > txmin) + if (tmin.y > tmin.x) { - txmin = tymin; + tmin.x = tmin.y; } - if (tymax < txmax) + if (tmax.y < tmax.x) { - txmax = tymax; + tmax.x = tmax.y; } - if (tzmin > tzmax) + if (tmin.z > tmax.z) { - std::swap(tzmin, tzmax); + std::swap(tmin.z, tmax.z); } - if ((txmin > tzmax) || (tzmin > txmax)) + if ((tmin.x > tmax.z) || (tmin.z > tmax.x)) { return 0; } - if (tzmin > txmin) + if (tmin.z > tmin.x) { - txmin = tzmin; + tmin.x = tmin.z; } - if (tzmax < txmax) + if (tmax.z < tmax.x) { - txmax = tzmax; + tmax.x = tmax.z; } int intersections = 2; - if (txmin < 0) + if (tmin.x < 0) { - if (txmax < 0) + if (tmax.x < 0) { return 0; } intersections--; - txmin = txmax; + tmin.x = tmax.x; } - p1.point = m_origin + txmin * m_dir; - p2.point = m_origin + txmax * m_dir; + p1.point = m_origin + tmin.x * m_dir; + p2.point = m_origin + tmax.x * m_dir; p1.distance2 = distance2(m_origin, p1.point); p2.distance2 = distance2(m_origin, p2.point); p1.normal = p2.normal = Math::Vector3f(0); @@ -179,15 +179,11 @@ namespace OpenVulkano::Scene std::optional Ray::IntersectPlane(const Math::Vector3f& pOrigin, const Math::Vector3f& pNorm) const { - RayHit hit; Math::Vector3f norm = normalize(pNorm); float d; if (intersectRayPlane(m_origin, m_dir, pOrigin, pNorm, d)) { - hit.SetDistance(d); - hit.point = m_origin + m_dir * d; - hit.normal = norm; - return hit; + return {{ m_origin + m_dir * d, norm, d, d * d }}; } return {}; } diff --git a/openVulkanoCpp/Scene/Ray.hpp b/openVulkanoCpp/Scene/Ray.hpp index 999888b..38b1f32 100644 --- a/openVulkanoCpp/Scene/Ray.hpp +++ b/openVulkanoCpp/Scene/Ray.hpp @@ -20,21 +20,32 @@ namespace OpenVulkano::Scene Math::Vector3f point; Math::Vector3f normal; float distance2; + + RayHit() : distance2(0), distance(-1) {} + + RayHit(Math::Vector3f point, Math::Vector3f normal, float distance2) + : point(point), normal(normal), distance2(distance2) + {} + + RayHit(Math::Vector3f point, Math::Vector3f normal, float distance, float distance2) + : point(point), normal(normal), distance2(distance2), distance(distance) + {} + [[nodiscard]] float GetDistance() const { - if (distance == -1) - { - distance = std::sqrt(distance2); - } + if (distance == -1) distance = std::sqrt(distance2); return distance; } + void SetDistance(float d) { this->distance = d; this->distance2 = d * d; } + bool operator==(const RayHit& other) const; bool operator!=(const RayHit& other) const; + private: mutable float distance = -1; }; @@ -66,6 +77,7 @@ namespace OpenVulkano::Scene const Math::Vector3f& n1, const Math::Vector3f& n2) const; [[nodiscard]] std::optional IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1, const Math::Vector3f& v2, const Math::Vector3f& v3) const; + [[nodiscard]] std::optional IntersectAABB(const Math::AABB2f& bbox) const; [[nodiscard]] std::optional IntersectAABB(const Math::AABB& bbox) const; int IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const; [[nodiscard]] std::optional IntersectPlane(const Math::Vector3f& pOrigin, diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 0af8ed4..60f2a6b 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -34,7 +34,7 @@ namespace OpenVulkano::Scene { VertexBuffer m_vertexBuffer; std::shared_ptr m_atlasData; - Math::AABB m_bbox; + Math::AABB2f m_bbox; std::string m_text; size_t m_symbolCount = 0; TextConfig m_cfg; @@ -51,7 +51,7 @@ namespace OpenVulkano::Scene void GenerateText(const std::string& text, const Math::Vector2f& pos = Math::Vector2f(0.f)); void SetConfig(const TextConfig& cfg) { m_cfg = cfg; } void SetAtlasData(const std::shared_ptr& atlasData); - [[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; } + [[nodiscard]] Math::AABB2f& GetBoundingBox() { return m_bbox; } [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } [[nodiscard]] const std::shared_ptr& GetAtlasData() { return m_atlasData; }