xmake.repo/packages/n/noesis/latest/Include/NsMath/AABBox.inl

227 lines
7.1 KiB
Plaintext
Raw Permalink Normal View History

2024-12-22 19:15:02 +08:00
////////////////////////////////////////////////////////////////////////////////////////////////////
// NoesisGUI - http://www.noesisengine.com
// Copyright (c) 2013 Noesis Technologies S.L. All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////
#include <NsCore/Error.h>
#include <float.h>
namespace Noesis
{
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2::AABBox2(): mMin(FLT_MAX, FLT_MAX), mMax(-FLT_MAX, -FLT_MAX)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2::AABBox2(float minX, float minY, float maxX, float maxY): mMin(minX, minY),
mMax(maxX, maxY)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2::AABBox2(const Vector2& min, const Vector2& max): mMin(min), mMax(max)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2::AABBox2(const Vector2& center, float halfSide)
{
NS_ASSERT(halfSide > 0.0f);
mMin = center - Vector2(halfSide, halfSide);
mMax = center + Vector2(halfSide, halfSide);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline void AABBox2::Reset()
{
mMin = Vector2(FLT_MAX, FLT_MAX);
mMax = Vector2(-FLT_MAX, -FLT_MAX);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline Vector2 AABBox2::operator[](uint32_t i) const
{
NS_ASSERT(i < 4);
return Vector2(i & 1 ? mMax[0] : mMin[0], i & 2 ? mMax[1] : mMin[1]);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline Vector2& AABBox2::Min()
{
return mMin;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const Vector2& AABBox2::Min() const
{
return mMin;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline Vector2& AABBox2::Max()
{
return mMax;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const Vector2& AABBox2::Max() const
{
return mMax;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline Vector2 AABBox2::Center() const
{
return 0.5f * (mMin + mMax);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline Vector2 AABBox2::Diagonal() const
{
return mMax - mMin;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2& AABBox2::operator+=(const AABBox2& box)
{
mMin[0] = Noesis::Min(box.mMin[0], mMin[0]);
mMin[1] = Noesis::Min(box.mMin[1], mMin[1]);
mMax[0] = Noesis::Max(box.mMax[0], mMax[0]);
mMax[1] = Noesis::Max(box.mMax[1], mMax[1]);
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2& AABBox2::operator+=(const Vector2& point)
{
mMin[0] = Noesis::Min(point[0], mMin[0]);
mMin[1] = Noesis::Min(point[1], mMin[1]);
mMax[0] = Noesis::Max(point[0], mMax[0]);
mMax[1] = Noesis::Max(point[1], mMax[1]);
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2& AABBox2::Scale(float s)
{
Vector2 center = Center();
mMin = (mMin - center) * s + center;
mMax = (mMax - center) * s + center;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool AABBox2::operator==(const AABBox2& box) const
{
return mMin == box.mMin && mMax == box.mMax;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool AABBox2::operator!=(const AABBox2& box) const
{
return !(*this == box);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool AABBox2::Empty() const
{
return mMax[0] < mMin[0] || mMax[1] < mMin[1];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const AABBox2 operator+(const AABBox2& box0, const AABBox2& box1)
{
AABBox2 ret(box0);
return ret += box1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const AABBox2 operator+(const AABBox2& box, const Vector2& point)
{
AABBox2 ret(box);
return ret += point;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const AABBox2 operator+(const Vector2& point, const AABBox2& box)
{
AABBox2 ret(box);
return ret += point;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const AABBox2 operator*(const AABBox2& box, const Transform2& mtx)
{
if (box.Empty()) return box;
AABBox2 ret(mtx[2], mtx[2]);
for (uint32_t i = 0; i < 2; i++)
{
for (uint32_t j = 0; j < 2; j++)
{
float a = mtx[j][i] * box.Min()[j];
float b = mtx[j][i] * box.Max()[j];
ret.Min()[i] += a < b ? a : b;
ret.Max()[i] += a < b ? b : a;
}
}
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const AABBox2 operator*(const AABBox2& box, float s)
{
AABBox2 ret(box);
ret.Scale(s);
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline const AABBox2 operator*(float s, const AABBox2& box)
{
AABBox2 ret(box);
ret.Scale(s);
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool Inside(const AABBox2& box, const Vector2& p)
{
return (p[0] > box.Min()[0] && p[1] > box.Min()[1] && p[0] < box.Max()[0]
&& p[1] < box.Max()[1]);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool BoxInside(const AABBox2& b0, const AABBox2& b1)
{
return b0.Min()[0] >= b1.Min()[0] && b0.Max()[0] <= b1.Max()[0] &&
b0.Min()[1] >= b1.Min()[1] && b0.Max()[1] <= b1.Max()[1];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool BoxesIntersect(const AABBox2& box0, const AABBox2& box1)
{
return (box0.Min()[0] < box1.Max()[0] && box0.Min()[1] < box1.Max()[1] &&
box0.Max()[0] > box1.Min()[0] && box0.Max()[1] > box1.Min()[1]);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
inline AABBox2 Intersect(const AABBox2& b0, const AABBox2& b1)
{
return AABBox2
(
Max(b0.Min()[0], b1.Min()[0]), Max(b0.Min()[1], b1.Min()[1]),
Min(b0.Max()[0], b1.Max()[0]), Min(b0.Max()[1], b1.Max()[1])
);
}
}