Files
LifeProject/LifeCore/BoundingBox3D.h
T
2025-05-13 02:46:21 +03:00

170 lines
4.0 KiB
C++

#ifndef BoundingBox3D_h__
#define BoundingBox3D_h__
#include "math/LifeMath.h"
namespace LifeCore
{
#undef INLINE
#ifdef _WIN32
#ifdef _MSC_VER
#define INLINE __forceinline
#endif
#else
#ifdef __GNUC__
#define INLINE __attribute__((always_inline))
#endif
#endif
#ifndef INLINE
#define INLINE inline
#endif
enum ContainmentType
{
Disjoint = 0,
Contains = 1,
Intersects = 2
};
class BoundingBox3D
{
public:
BoundingBox3D()
{
vMin = LifeMath::float3(1000000000, 1000000000, 1000000000);
vMax = LifeMath::float3(-1000000000, -1000000000, -1000000000);
}
INLINE BoundingBox3D& operator=(const BoundingBox3D& other)
{
vMin = other.minimum();
vMax = other.maximum();
return *this;
}
BoundingBox3D(float size)
{
float offset = size/2.0f;
vMin = LifeMath::float3(-offset, -offset, -offset);
vMax = LifeMath::float3(offset, offset, offset);
}
BoundingBox3D(LifeMath::float3& minPoint, LifeMath::float3& maxPoint)
{
vMin = minPoint;
vMax = maxPoint;
}
BoundingBox3D(LifeMath::float4& minPoint, LifeMath::float4& maxPoint)
{
vMin = LifeMath::float3(minPoint.X, minPoint.Y, minPoint.Z);
vMax = LifeMath::float3(maxPoint.X, maxPoint.Y, maxPoint.Z);
}
const LifeMath::float3 maximum() const
{
return vMax;
}
LifeMath::float3 size() const
{
return vMax - vMin;
}
const LifeMath::float3 minimum() const
{
return vMin;
}
void resize(const LifeMath::float3& min, const LifeMath::float3& max)
{
vMin = min;
vMax = max;
}
float sizeX() const
{
return vMax.X - vMin.X;
}
float sizeY() const
{
return vMax.Y - vMin.Y;
}
float sizeZ() const
{
return vMax.Z - vMin.Z;
}
~BoundingBox3D()
{
}
void Merge(BoundingBox3D& box)
{
Vec3Maximize(this->vMax, box.maximum(), this->vMax);
Vec3Minimize(this->vMin, box.minimum(), this->vMin);
}
BoundingBox3D Clone()
{
return BoundingBox3D(vMin, vMax);
}
static BoundingBox3D FromPoints(LifeMath::float4* points, int count)
{
LifeMath::float4 min = points[0];
LifeMath::float4 max = min;
for (int i = 0; i < count; i++)
{
Vec4Minimize(min, points[i], min);
Vec4Maximize(max, points[i], max);
}
return BoundingBox3D(min, max);
}
static BoundingBox3D FromPoints(LifeMath::float3* points, int count)
{
LifeMath::float3 min = points[0];
LifeMath::float3 max = min;
for (int i = 0; i < count; i++)
{
Vec3Minimize(min, points[i], min);
Vec3Maximize(max, points[i], max);
}
return BoundingBox3D(min, max);
}
static ContainmentType ContainsBox( BoundingBox3D& box1, BoundingBox3D& box2)
{
if ((box1.maximum().X < box2.minimum().X) || (box1.minimum().X > box2.maximum().X))
{
return Disjoint;
}
if ((box1.maximum().Y < box2.minimum().Y) || (box1.minimum().Y > box2.maximum().Y))
{
return Disjoint;
}
if ((box1.maximum().Z < box2.minimum().Z) || (box1.minimum().Z > box2.maximum().Z))
{
return Disjoint;
}
if ((((box1.minimum().X <= box2.minimum().X) && (box2.maximum().X <= box1.maximum().X)) && ((box1.minimum().Y <= box2.minimum().Y) && (box2.maximum().Y <= box1.maximum().Y))) && ((box1.minimum().Z <= box2.minimum().Z) && (box2.maximum().Z <= box1.maximum().Z)))
{
return Contains;
}
return Intersects;
}
void GetCorners(LifeMath::float3* corners) const
{
// 5________6
// / /
// / /
// /________2/
// 1 | 7
// | |
// | |
// 0---------3
corners[0] = LifeMath::float3(vMin.X, vMin.Y, vMin.Z);
corners[1] = LifeMath::float3(vMin.X, vMax.Y, vMin.Z);
corners[2] = LifeMath::float3(vMax.X, vMax.Y, vMin.Z);
corners[3] = LifeMath::float3(vMax.X, vMin.Y, vMin.Z);
corners[4] = LifeMath::float3(vMin.X, vMin.Y, vMax.Z);
corners[5] = LifeMath::float3(vMin.X, vMax.Y, vMax.Z);
corners[6] = LifeMath::float3(vMax.X, vMax.Y, vMax.Z);
corners[7] = LifeMath::float3(vMax.X, vMin.Y, vMax.Z);
}
private:
LifeMath::float3 vMin;
LifeMath::float3 vMax;
};
}
#endif // BoundingBox3D_h__