202 lines
4.5 KiB
C++
202 lines
4.5 KiB
C++
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "../../Platform/Platform.h"
|
|
#include "Vector3.h"
|
|
|
|
/// <summary>
|
|
/// Integer axis aligned bounding box
|
|
/// </summary>
|
|
struct AABB
|
|
{
|
|
public:
|
|
|
|
int32 MinX;
|
|
int32 MaxX;
|
|
|
|
int32 MinY;
|
|
int32 MaxY;
|
|
|
|
int32 MinZ;
|
|
int32 MaxZ;
|
|
|
|
public:
|
|
|
|
AABB()
|
|
{
|
|
MinX = MAX_int32;
|
|
MaxX = MIN_int32;
|
|
MinY = MAX_int32;
|
|
MaxY = MIN_int32;
|
|
MinZ = MAX_int32;
|
|
MaxZ = MIN_int32;
|
|
}
|
|
|
|
AABB(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
|
|
{
|
|
MinX = (int32)minX;
|
|
MaxX = (int32)maxX;
|
|
MinY = (int32)minY;
|
|
MaxY = (int32)maxY;
|
|
MinZ = (int32)minZ;
|
|
MaxZ = (int32)maxZ;
|
|
}
|
|
|
|
AABB(const AABB& other)
|
|
{
|
|
Set(other);
|
|
}
|
|
|
|
public:
|
|
|
|
int32 Width() const
|
|
{
|
|
return MaxX - MinX;
|
|
}
|
|
|
|
int32 Height() const
|
|
{
|
|
return MaxY - MinY;
|
|
}
|
|
|
|
int32 Depth() const
|
|
{
|
|
return MaxZ - MinZ;
|
|
}
|
|
|
|
int32 X() const
|
|
{
|
|
return (MaxX + MinX) / 2;
|
|
}
|
|
|
|
int32 Y() const
|
|
{
|
|
return (MaxY + MinY) / 2;
|
|
}
|
|
|
|
int32 Z() const
|
|
{
|
|
return (MaxZ + MinZ) / 2;
|
|
}
|
|
|
|
bool IsEmpty() const
|
|
{
|
|
return MinX >= MaxX || MinY >= MaxY || MinZ >= MaxZ;
|
|
}
|
|
|
|
public:
|
|
|
|
void Clear()
|
|
{
|
|
MinX = MAX_int32;
|
|
MaxX = MIN_int32;
|
|
MinY = MAX_int32;
|
|
MaxY = MIN_int32;
|
|
MinZ = MAX_int32;
|
|
MaxZ = MIN_int32;
|
|
}
|
|
|
|
void Add(const Vector3& inCoordinate)
|
|
{
|
|
Add(inCoordinate.X, inCoordinate.Y, inCoordinate.Z);
|
|
}
|
|
|
|
void Add(float inX, float inY, float inZ)
|
|
{
|
|
ASSERT(!isinf(inX) && !isnan(inX));
|
|
ASSERT(!isinf(inY) && !isnan(inY));
|
|
ASSERT(!isinf(inZ) && !isnan(inZ));
|
|
|
|
MinX = Math::Min(MinX, (int32)Math::Floor(inX));
|
|
MinY = Math::Min(MinY, (int32)Math::Floor(inY));
|
|
MinZ = Math::Min(MinZ, (int32)Math::Floor(inZ));
|
|
|
|
MaxX = Math::Max(MaxX, (int32)Math::Ceil(inX));
|
|
MaxY = Math::Max(MaxY, (int32)Math::Ceil(inY));
|
|
MaxZ = Math::Max(MaxZ, (int32)Math::Ceil(inZ));
|
|
}
|
|
|
|
void Add(const AABB& bounds)
|
|
{
|
|
MinX = Math::Min(MinX, bounds.MinX);
|
|
MinY = Math::Min(MinY, bounds.MinY);
|
|
MinZ = Math::Min(MinZ, bounds.MinZ);
|
|
|
|
MaxX = Math::Max(MaxX, bounds.MaxX);
|
|
MaxY = Math::Max(MaxY, bounds.MaxY);
|
|
MaxZ = Math::Max(MaxZ, bounds.MaxZ);
|
|
}
|
|
|
|
void Set(const AABB& bounds)
|
|
{
|
|
MinX = bounds.MinX;
|
|
MinY = bounds.MinY;
|
|
MinZ = bounds.MinZ;
|
|
|
|
MaxX = bounds.MaxX;
|
|
MaxY = bounds.MaxY;
|
|
MaxZ = bounds.MaxZ;
|
|
}
|
|
|
|
void Translate(int32 X, int32 Y, int32 Z)
|
|
{
|
|
MinX += X;
|
|
MinY += Y;
|
|
MinZ += Z;
|
|
|
|
MaxX += X;
|
|
MaxY += Y;
|
|
MaxZ += Z;
|
|
}
|
|
|
|
void Translate(const Vector3& translation)
|
|
{
|
|
MinX = (int32)Math::Floor(MinX + translation.X);
|
|
MinY = (int32)Math::Floor(MinY + translation.Y);
|
|
MinZ = (int32)Math::Floor(MinZ + translation.Z);
|
|
|
|
MaxX = (int32)Math::Ceil(MaxX + translation.X);
|
|
MaxY = (int32)Math::Ceil(MaxY + translation.Y);
|
|
MaxZ = (int32)Math::Ceil(MaxZ + translation.Z);
|
|
}
|
|
|
|
AABB Translated(const Vector3& translation) const
|
|
{
|
|
return AABB(MinX + translation.X,
|
|
MinY + translation.Y,
|
|
MinZ + translation.Z,
|
|
|
|
MaxX + translation.X,
|
|
MaxY + translation.Y,
|
|
MaxZ + translation.Z);
|
|
}
|
|
|
|
void Set(const AABB& other, const Vector3& translation)
|
|
{
|
|
MinX = (int32)Math::Floor(other.MinX + translation.X);
|
|
MinY = (int32)Math::Floor(other.MinY + translation.Y);
|
|
MinZ = (int32)Math::Floor(other.MinZ + translation.Z);
|
|
|
|
MaxX = (int32)Math::Ceil(other.MaxX + translation.X);
|
|
MaxY = (int32)Math::Ceil(other.MaxY + translation.Y);
|
|
MaxZ = (int32)Math::Ceil(other.MaxZ + translation.Z);
|
|
}
|
|
|
|
public:
|
|
|
|
bool IsOutside(const AABB& other) const
|
|
{
|
|
return MaxX - other.MinX < 0 || MinX - other.MaxX > 0 ||
|
|
MaxY - other.MinY < 0 || MinY - other.MaxY > 0 ||
|
|
MaxZ - other.MinZ < 0 || MinZ - other.MaxZ > 0;
|
|
}
|
|
|
|
static bool IsOutside(const AABB& left, const AABB& right)
|
|
{
|
|
return left.MaxX - right.MinX < 0 || left.MinX - right.MaxX > 0 ||
|
|
left.MaxY - right.MinY < 0 || left.MinY - right.MaxY > 0 ||
|
|
left.MaxZ - right.MinZ < 0 || left.MinZ - right.MaxZ > 0;
|
|
}
|
|
};
|