143 lines
3.7 KiB
C++
143 lines
3.7 KiB
C++
/*
|
|
* 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<typename T>
|
|
class AABB_T final : public Range<T>
|
|
{
|
|
public:
|
|
AABB_T() : Range<T>(T(INFINITY), T(-INFINITY)) {}
|
|
|
|
AABB_T(const T& min, const T& max) : Range<T>(min, max) {}
|
|
|
|
AABB_T(const T& point) : Range<T>(point, point)
|
|
{}
|
|
|
|
AABB_T(const T& point, float radius) : Range<T>(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<T>::min = Range<T>::max = point;
|
|
}
|
|
|
|
void Init(const T& min, const T& max)
|
|
{
|
|
this->min = min;
|
|
this->max = max;
|
|
}
|
|
|
|
void Init(const T& point, float radius)
|
|
{
|
|
Range<T>::min = point - radius;
|
|
Range<T>::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<T>::min = other.GetMin();
|
|
Range<T>::max = other.GetMax();
|
|
}
|
|
|
|
void Grow(const T& point)
|
|
{
|
|
Range<T>::min = Math::Utils::min(Range<T>::min, point);
|
|
Range<T>::max = Math::Utils::max(Range<T>::max, point);
|
|
}
|
|
|
|
void Grow(const AABB_T& otherAABB)
|
|
{
|
|
Range<T>::min = Math::Utils::min(Range<T>::min, otherAABB.GetMin());
|
|
Range<T>::max = Math::Utils::max(Range<T>::max, otherAABB.GetMax());
|
|
}
|
|
|
|
void Grow(const AABB_T& otherAABB, Math::Matrix4f transformation)
|
|
{
|
|
//TODO
|
|
}
|
|
|
|
[[nodiscard]] T GetDiagonal() const
|
|
{
|
|
return Range<T>::GetSize();
|
|
}
|
|
|
|
[[nodiscard]] T GetCenter() const
|
|
{
|
|
return Range<T>::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<T>::max)) && Math::Utils::all(Math::Utils::greaterThanEqual(Range<T>::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<T>::min, other.GetMax())) && Math::Utils::all(Math::Utils::greaterThanEqual(Range<T>::max, other.GetMin()));
|
|
}
|
|
|
|
[[nodiscard]] bool InBounds(const T& position) const
|
|
{
|
|
return Math::Utils::all(Math::Utils::lessThanEqual(Range<T>::min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, Range<T>::max));
|
|
}
|
|
|
|
[[nodiscard]] bool Inside(const T& position) const
|
|
{
|
|
return Math::Utils::all(Math::Utils::lessThan(Range<T>::min, position)) && Math::Utils::all(Math::Utils::lessThan(position, Range<T>::max));
|
|
}
|
|
|
|
[[nodiscard]] bool IsEmpty() const
|
|
{
|
|
return Range<T>::min == T(INFINITY) && Range<T>::max == T(-INFINITY);
|
|
}
|
|
|
|
/**
|
|
* \brief Resets the AABB to min=Inf, max=-Inf, same as Init()
|
|
*/
|
|
void Reset()
|
|
{
|
|
Range<T>::min = T(INFINITY);
|
|
Range<T>::max = T(-INFINITY);
|
|
}
|
|
|
|
AABB_T& operator +=(const AABB_T& other) { Grow(other); return *this; }
|
|
|
|
AABB_T& operator +=(const T& point) { Grow(point); return *this; }
|
|
|
|
[[nodiscard]] operator bool() const { return !IsEmpty(); }
|
|
};
|
|
|
|
typedef AABB_T<Vector3f> AABB;
|
|
typedef AABB_T<Vector2f> AABB2f;
|
|
}
|