170 lines
4.0 KiB
C++
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__
|