#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__