/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "Math.hpp" #include "Range.hpp" namespace OpenVulkano::Math { /** * \brief A class that represents an axis aligned bounding box */ template class AABB_T final : public Range { public: AABB_T() : Range(T(INFINITY), T(-INFINITY)) {} AABB_T(const T& min, const T& max) : Range(min, max) {} AABB_T(const T& point) : Range(point, point) {} 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 T& point) { Range::min = Range::max = point; } void Init(const T& min, const T& max) { this->min = min; this->max = max; } void Init(const T& point, float 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_T& other) { Range::min = other.GetMin(); Range::max = other.GetMax(); } void Grow(const T& point) { Range::min = Math::Utils::min(Range::min, point); Range::max = Math::Utils::max(Range::max, point); } void Grow(const AABB_T& otherAABB) { Range::min = Math::Utils::min(Range::min, otherAABB.GetMin()); Range::max = Math::Utils::max(Range::max, otherAABB.GetMax()); } void Grow(const AABB_T& otherAABB, Math::Matrix4f transformation) { //TODO } [[nodiscard]] T GetDiagonal() const { return Range::GetSize(); } [[nodiscard]] T GetCenter() const { return Range::min + (GetDiagonal() * 0.5f); } [[nodiscard]] bool Covers(const AABB_T& other) const { return other.IsCovered(*this); } [[nodiscard]] bool IsCovered(const AABB_T& other) const { return Math::Utils::all(Math::Utils::greaterThanEqual(other.GetMax(), Range::max)) && Math::Utils::all(Math::Utils::greaterThanEqual(Range::min, other.GetMin())); } /** * \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_T& other) const { return Math::Utils::all(Math::Utils::lessThanEqual(Range::min, other.GetMax())) && Math::Utils::all(Math::Utils::greaterThanEqual(Range::max, other.GetMin())); } [[nodiscard]] bool InBounds(const T& position) const { return Math::Utils::all(Math::Utils::lessThanEqual(Range::min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, Range::max)); } [[nodiscard]] bool Inside(const T& position) const { return Math::Utils::all(Math::Utils::lessThan(Range::min, position)) && Math::Utils::all(Math::Utils::lessThan(position, Range::max)); } [[nodiscard]] bool IsEmpty() const { return Range::min == T(INFINITY) && Range::max == T(-INFINITY); } /** * \brief Resets the AABB to min=Inf, max=-Inf, same as Init() */ void Reset() { Range::min = T(INFINITY); Range::max = T(-INFINITY); } AABB_T& operator +=(const AABB_T& other) { Grow(other); return *this; } }; typedef AABB_T AABB; typedef AABB_T AABB2f; }