102 lines
3.0 KiB
C++
102 lines
3.0 KiB
C++
/// Josh's 3D Math Library
|
|
/// A C++20 Library for 3D Math, Computer Graphics, and Scientific Computing.
|
|
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
|
|
/// Special Thanks to William Tomasine II and Maxine Hayes.
|
|
/// (c) 2024 Redacted Software
|
|
/// This work is dedicated to the public domain.
|
|
|
|
/// @file AABB2D.hpp
|
|
/// @desc A 2D Axis-Aligned Bounding Box structure.
|
|
/// @edit 2025-04-18
|
|
|
|
#pragma once
|
|
|
|
#include <J3ML/LinearAlgebra.hpp>
|
|
#include <J3ML/Geometry/Shape.hpp>
|
|
#include <J3ML/Geometry/Forward.hpp>
|
|
|
|
|
|
/// See Christer Ericson's Real-time Collision Detection, p. 87, or
|
|
/// James Arvo's "Transforming Axis-aligned Bounding Boxes" in Graphics Gems 1, pp. 548-550.
|
|
/// http://www.graphicsgems.org/
|
|
template <typename Matrix>
|
|
void AABB2DTransformAsAABB2D(AABB2D& aabb, Matrix& m);
|
|
|
|
namespace J3ML::Geometry
|
|
{
|
|
using LinearAlgebra::Vector2;
|
|
|
|
// TODO: Integer AABB2D for even leaner box computation.
|
|
|
|
// CaveGame AABB
|
|
class AABB2D : public Shape2D
|
|
{
|
|
public:
|
|
|
|
Vector2 minPoint;
|
|
Vector2 maxPoint;
|
|
AABB2D() {}
|
|
AABB2D(const Vector2& min, const Vector2& max):
|
|
minPoint(min), maxPoint(max)
|
|
{}
|
|
|
|
[[nodiscard]] float Width() const;
|
|
[[nodiscard]] float Height() const;
|
|
|
|
Vector2 Centroid() const;
|
|
|
|
[[nodiscard]] float DistanceSq(const Vector2& pt) const;
|
|
|
|
void SetNegativeInfinity();
|
|
|
|
void Enclose(const Vector2& point);
|
|
|
|
[[nodiscard]] bool Intersects(const AABB2D& rhs) const;
|
|
|
|
[[nodiscard]] bool Contains(const AABB2D& rhs) const;
|
|
|
|
[[nodiscard]] bool Contains(const Vector2& pt) const;
|
|
|
|
[[nodiscard]] bool Contains(int x, int y) const;
|
|
|
|
[[nodiscard]] bool IsDegenerate() const;
|
|
|
|
[[nodiscard]] bool HasNegativeVolume() const;
|
|
|
|
[[nodiscard]] bool IsFinite() const;
|
|
|
|
Vector2 PosInside(const Vector2 &normalizedPos) const;
|
|
|
|
Vector2 ToNormalizedLocalSpace(const Vector2 &pt) const;
|
|
|
|
AABB2D operator+(const Vector2& pt) const;
|
|
|
|
AABB2D operator-(const Vector2& pt) const;
|
|
|
|
Vector2 CornerPoint(int cornerIndex);
|
|
|
|
void TransformAsAABB(const Matrix3x3& transform);
|
|
void TransformAsAABB(const Matrix4x4& transform);
|
|
|
|
|
|
};
|
|
|
|
template<typename Matrix>
|
|
void AABB2DTransformAsAABB2D(AABB2D &aabb, Matrix &m) {
|
|
float ax = m[0][0] * aabb.minPoint.x;
|
|
float bx = m[0][0] * aabb.maxPoint.x;
|
|
float ay = m[0][1] * aabb.minPoint.y;
|
|
float by = m[0][1] * aabb.maxPoint.y;
|
|
|
|
float ax2 = m[1][0] * aabb.minPoint.x;
|
|
float bx2 = m[1][0] * aabb.maxPoint.x;
|
|
float ay2 = m[1][1] * aabb.minPoint.y;
|
|
float by2 = m[1][1] * aabb.maxPoint.y;
|
|
|
|
aabb.minPoint.x = J3ML::Math::Min(ax, bx) + J3ML::Math::Min(ay, by) + m[0][3];
|
|
aabb.maxPoint.x = J3ML::Math::Max(ax, bx) + J3ML::Math::Max(ay, by) + m[0][3];
|
|
|
|
aabb.minPoint.y = J3ML::Math::Min(ax2, bx2) + J3ML::Math::Min(ay2, by2) + m[1][3];
|
|
aabb.maxPoint.y = J3ML::Math::Max(ax2, bx2) + J3ML::Math::Max(ay2, by2) + m[1][3];
|
|
}
|
|
} |