Add 2d variant of bounding box
This commit is contained in:
@@ -14,75 +14,76 @@ namespace OpenVulkano::Math
|
|||||||
/**
|
/**
|
||||||
* \brief A class that represents an axis aligned bounding box
|
* \brief A class that represents an axis aligned bounding box
|
||||||
*/
|
*/
|
||||||
class AABB final : public Range<Vector3f>
|
template<typename T>
|
||||||
|
class AABB_T final : public Range<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AABB() : Range(Vector3f(INFINITY), Vector3f(-INFINITY)) {}
|
AABB_T() : Range<T>(T(INFINITY), T(-INFINITY)) {}
|
||||||
|
|
||||||
AABB(const Vector3f& min, const Vector3f& max) : Range(min, max) {}
|
AABB_T(const T& min, const T& max) : Range<T>(min, max) {}
|
||||||
|
|
||||||
AABB(const Vector3f& point) : Range(point, point)
|
AABB_T(const T& point) : Range<T>(point, point)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
AABB(const Vector3f& point, float radius) : Range(point - radius, point + radius)
|
AABB_T(const T& point, float radius) : Range<T>(point - radius, point + radius)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initiates the AABB to a single point (min=max=point)
|
* \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
|
* \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<T>::min = Range<T>::max = point;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(const Vector3f& min, const Vector3f& max)
|
void Init(const T& min, const T& max)
|
||||||
{
|
{
|
||||||
this->min = min;
|
this->min = min;
|
||||||
this->max = max;
|
this->max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(const Vector3f& point, float radius)
|
void Init(const T& point, float radius)
|
||||||
{
|
{
|
||||||
min = point - radius;
|
Range<T>::min = point - radius;
|
||||||
max = point + radius;
|
Range<T>::max = point + radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initiates the AABB from some other AABB
|
* \brief Initiates the AABB from some other AABB
|
||||||
* \param other The other AABB that should be copied
|
* \param other The other AABB that should be copied
|
||||||
*/
|
*/
|
||||||
void Init(const AABB& other)
|
void Init(const AABB_T& other)
|
||||||
{
|
{
|
||||||
min = other.GetMin();
|
Range<T>::min = other.GetMin();
|
||||||
max = other.GetMax();
|
Range<T>::max = other.GetMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Grow(const Vector3f& point)
|
void Grow(const T& point)
|
||||||
{
|
{
|
||||||
min = Math::Utils::min(min, point);
|
Range<T>::min = Math::Utils::min(Range<T>::min, point);
|
||||||
max = Math::Utils::max(max, point);
|
Range<T>::max = Math::Utils::max(Range<T>::max, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Grow(const AABB& otherAABB)
|
void Grow(const AABB_T& otherAABB)
|
||||||
{
|
{
|
||||||
min = Math::Utils::min(min, otherAABB.GetMin());
|
Range<T>::min = Math::Utils::min(Range<T>::min, otherAABB.GetMin());
|
||||||
max = Math::Utils::max(max, otherAABB.GetMax());
|
Range<T>::max = Math::Utils::max(Range<T>::max, otherAABB.GetMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Grow(const AABB& otherAABB, Math::Matrix4f transformation)
|
void Grow(const AABB_T& otherAABB, Math::Matrix4f transformation)
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Vector3f GetDiagonal() const
|
[[nodiscard]] T GetDiagonal() const
|
||||||
{
|
{
|
||||||
return GetSize();
|
return Range<T>::GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Vector3f GetCenter() const
|
[[nodiscard]] T GetCenter() const
|
||||||
{
|
{
|
||||||
return min + (GetDiagonal() * 0.5f);
|
return Range<T>::min + (GetDiagonal() * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,25 +91,26 @@ namespace OpenVulkano::Math
|
|||||||
* \param other The other AABB that should be checked
|
* \param other The other AABB that should be checked
|
||||||
* \return true if the AABB overlaps with the other, false if not
|
* \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 ||
|
//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);
|
// other.max.y < min.y || other.min.z > max.z || other.max.z < min.z);
|
||||||
|
return Math::Utils::any(Math::Utils::greaterThan(Range<T>::min, other.GetMin())) || Math::Utils::any(Math::Utils::lessThan(other.GetMax(), Range<T>::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<T>::min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, Range<T>::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<T>::min, position)) && Math::Utils::all(Math::Utils::lessThan(position, Range<T>::max));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool IsEmpty() const
|
[[nodiscard]] bool IsEmpty() const
|
||||||
{
|
{
|
||||||
return min == Math::Vector3f(INFINITY) && max == Math::Vector3f(-INFINITY);
|
return Range<T>::min == T(INFINITY) && Range<T>::max == T(-INFINITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,10 +118,13 @@ namespace OpenVulkano::Math
|
|||||||
*/
|
*/
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
min = Vector3f(INFINITY);
|
Range<T>::min = T(INFINITY);
|
||||||
max = Vector3f(-INFINITY);
|
Range<T>::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<Vector3f> AABB;
|
||||||
|
typedef AABB_T<Vector2f> AABB2f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace OpenVulkano::Scene
|
|||||||
[[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; }
|
[[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; }
|
||||||
[[nodiscard]] Math::Vector3f& GetPosition() { return m_position; }
|
[[nodiscard]] Math::Vector3f& GetPosition() { return m_position; }
|
||||||
[[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; }
|
[[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<RayHit> Intersect(const Ray& ray) const override;
|
std::optional<RayHit> Intersect(const Ray& ray) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -63,6 +63,6 @@ namespace OpenVulkano::Scene
|
|||||||
LabelDrawableSettings m_settings;
|
LabelDrawableSettings m_settings;
|
||||||
LabelUniformData m_labelData;
|
LabelUniformData m_labelData;
|
||||||
Math::Vector3f m_position = { 0, 0, 0 };
|
Math::Vector3f m_position = { 0, 0, 0 };
|
||||||
Math::AABB m_bbox;
|
Math::AABB2f m_bbox;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,12 @@ namespace OpenVulkano::Scene
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<RayHit> 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<RayHit> Ray::IntersectAABB(const Math::AABB& bbox) const
|
std::optional<RayHit> Ray::IntersectAABB(const Math::AABB& bbox) const
|
||||||
{
|
{
|
||||||
RayHit h1, h2;
|
RayHit h1, h2;
|
||||||
@@ -108,69 +114,63 @@ namespace OpenVulkano::Scene
|
|||||||
|
|
||||||
int Ray::IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const
|
int Ray::IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const
|
||||||
{
|
{
|
||||||
const auto tmin = (bbox.min - m_origin) / m_dir;
|
auto tmin = (bbox.min - m_origin) / m_dir;
|
||||||
const auto tmax = (bbox.max - m_origin) / m_dir;
|
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;
|
|
||||||
|
|
||||||
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;
|
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;
|
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;
|
int intersections = 2;
|
||||||
if (txmin < 0)
|
if (tmin.x < 0)
|
||||||
{
|
{
|
||||||
if (txmax < 0)
|
if (tmax.x < 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
intersections--;
|
intersections--;
|
||||||
txmin = txmax;
|
tmin.x = tmax.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
p1.point = m_origin + txmin * m_dir;
|
p1.point = m_origin + tmin.x * m_dir;
|
||||||
p2.point = m_origin + txmax * m_dir;
|
p2.point = m_origin + tmax.x * m_dir;
|
||||||
p1.distance2 = distance2(m_origin, p1.point);
|
p1.distance2 = distance2(m_origin, p1.point);
|
||||||
p2.distance2 = distance2(m_origin, p2.point);
|
p2.distance2 = distance2(m_origin, p2.point);
|
||||||
p1.normal = p2.normal = Math::Vector3f(0);
|
p1.normal = p2.normal = Math::Vector3f(0);
|
||||||
@@ -179,15 +179,11 @@ namespace OpenVulkano::Scene
|
|||||||
|
|
||||||
std::optional<RayHit> Ray::IntersectPlane(const Math::Vector3f& pOrigin, const Math::Vector3f& pNorm) const
|
std::optional<RayHit> Ray::IntersectPlane(const Math::Vector3f& pOrigin, const Math::Vector3f& pNorm) const
|
||||||
{
|
{
|
||||||
RayHit hit;
|
|
||||||
Math::Vector3f norm = normalize(pNorm);
|
Math::Vector3f norm = normalize(pNorm);
|
||||||
float d;
|
float d;
|
||||||
if (intersectRayPlane(m_origin, m_dir, pOrigin, pNorm, d))
|
if (intersectRayPlane(m_origin, m_dir, pOrigin, pNorm, d))
|
||||||
{
|
{
|
||||||
hit.SetDistance(d);
|
return {{ m_origin + m_dir * d, norm, d, d * d }};
|
||||||
hit.point = m_origin + m_dir * d;
|
|
||||||
hit.normal = norm;
|
|
||||||
return hit;
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,21 +20,32 @@ namespace OpenVulkano::Scene
|
|||||||
Math::Vector3f point;
|
Math::Vector3f point;
|
||||||
Math::Vector3f normal;
|
Math::Vector3f normal;
|
||||||
float distance2;
|
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
|
[[nodiscard]] float GetDistance() const
|
||||||
{
|
{
|
||||||
if (distance == -1)
|
if (distance == -1) distance = std::sqrt(distance2);
|
||||||
{
|
|
||||||
distance = std::sqrt(distance2);
|
|
||||||
}
|
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDistance(float d)
|
void SetDistance(float d)
|
||||||
{
|
{
|
||||||
this->distance = d;
|
this->distance = d;
|
||||||
this->distance2 = d * d;
|
this->distance2 = d * d;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const RayHit& other) const;
|
bool operator==(const RayHit& other) const;
|
||||||
bool operator!=(const RayHit& other) const;
|
bool operator!=(const RayHit& other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable float distance = -1;
|
mutable float distance = -1;
|
||||||
};
|
};
|
||||||
@@ -66,6 +77,7 @@ namespace OpenVulkano::Scene
|
|||||||
const Math::Vector3f& n1, const Math::Vector3f& n2) const;
|
const Math::Vector3f& n1, const Math::Vector3f& n2) const;
|
||||||
[[nodiscard]] std::optional<RayHit> IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1,
|
[[nodiscard]] std::optional<RayHit> IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1,
|
||||||
const Math::Vector3f& v2, const Math::Vector3f& v3) const;
|
const Math::Vector3f& v2, const Math::Vector3f& v3) const;
|
||||||
|
[[nodiscard]] std::optional<RayHit> IntersectAABB(const Math::AABB2f& bbox) const;
|
||||||
[[nodiscard]] std::optional<RayHit> IntersectAABB(const Math::AABB& bbox) const;
|
[[nodiscard]] std::optional<RayHit> IntersectAABB(const Math::AABB& bbox) const;
|
||||||
int IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const;
|
int IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const;
|
||||||
[[nodiscard]] std::optional<RayHit> IntersectPlane(const Math::Vector3f& pOrigin,
|
[[nodiscard]] std::optional<RayHit> IntersectPlane(const Math::Vector3f& pOrigin,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace OpenVulkano::Scene
|
|||||||
{
|
{
|
||||||
VertexBuffer m_vertexBuffer;
|
VertexBuffer m_vertexBuffer;
|
||||||
std::shared_ptr<AtlasData> m_atlasData;
|
std::shared_ptr<AtlasData> m_atlasData;
|
||||||
Math::AABB m_bbox;
|
Math::AABB2f m_bbox;
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
size_t m_symbolCount = 0;
|
size_t m_symbolCount = 0;
|
||||||
TextConfig m_cfg;
|
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 GenerateText(const std::string& text, const Math::Vector2f& pos = Math::Vector2f(0.f));
|
||||||
void SetConfig(const TextConfig& cfg) { m_cfg = cfg; }
|
void SetConfig(const TextConfig& cfg) { m_cfg = cfg; }
|
||||||
void SetAtlasData(const std::shared_ptr<AtlasData>& atlasData);
|
void SetAtlasData(const std::shared_ptr<AtlasData>& atlasData);
|
||||||
[[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; }
|
[[nodiscard]] Math::AABB2f& GetBoundingBox() { return m_bbox; }
|
||||||
[[nodiscard]] TextConfig& GetConfig() { return m_cfg; }
|
[[nodiscard]] TextConfig& GetConfig() { return m_cfg; }
|
||||||
[[nodiscard]] const std::string& GetText() const { return m_text; }
|
[[nodiscard]] const std::string& GetText() const { return m_text; }
|
||||||
[[nodiscard]] const std::shared_ptr<AtlasData>& GetAtlasData() { return m_atlasData; }
|
[[nodiscard]] const std::shared_ptr<AtlasData>& GetAtlasData() { return m_atlasData; }
|
||||||
|
|||||||
Reference in New Issue
Block a user