///////////////////////////////////////////////////////////////////////////////
//  CBoundingBox.cpp

#include <float.h>
#include <algorithm>
#include "CBoundingBox.h"

namespace math3d {
	
CBoundingBox::CBoundingBox(void)
{
	Clear();
}

CBoundingBox::~CBoundingBox()
{
}

void CBoundingBox::Clear(void)
{
	m_fMinX = FLT_MAX;
	m_fMaxX = -FLT_MAX;
	m_fMinY = FLT_MAX;
	m_fMaxY = -FLT_MAX;
	m_fMinZ = FLT_MAX;
	m_fMaxZ = -FLT_MAX;
}

void CBoundingBox::Insert(const S3D& Pos)
{
	if (m_fMinX > Pos.fX) m_fMinX = Pos.fX;
	if (m_fMaxX < Pos.fX) m_fMaxX = Pos.fX;
	if (m_fMinY > Pos.fY) m_fMinY = Pos.fY;
	if (m_fMaxY < Pos.fY) m_fMaxY = Pos.fY;
	if (m_fMinZ > Pos.fZ) m_fMinZ = Pos.fZ;
	if (m_fMaxZ < Pos.fZ) m_fMaxZ = Pos.fZ;
}

void CBoundingBox::InsertSphere(const S3D& Pos, float Radius)
{
	if (m_fMinX > (Pos.fX - Radius)) m_fMinX = Pos.fX - Radius;
	if (m_fMaxX < (Pos.fX + Radius)) m_fMaxX = Pos.fX + Radius;
	if (m_fMinY > (Pos.fY - Radius)) m_fMinY = Pos.fY - Radius;
	if (m_fMaxY < (Pos.fY + Radius)) m_fMaxY = Pos.fY + Radius;
	if (m_fMinZ > (Pos.fZ - Radius)) m_fMinZ = Pos.fZ - Radius;
	if (m_fMaxZ < (Pos.fZ + Radius)) m_fMaxZ = Pos.fZ + Radius;
}

void CBoundingBox::InsertBoundingBox(const CBoundingBox& BoundingBox)
{
	if (m_fMinX > BoundingBox.m_fMinX) m_fMinX = BoundingBox.m_fMinX;
	if (m_fMaxX < BoundingBox.m_fMaxX) m_fMaxX = BoundingBox.m_fMaxX;
	if (m_fMinY > BoundingBox.m_fMinY) m_fMinY = BoundingBox.m_fMinY;
	if (m_fMaxY < BoundingBox.m_fMaxY) m_fMaxY = BoundingBox.m_fMaxY;
	if (m_fMinZ > BoundingBox.m_fMinZ) m_fMinZ = BoundingBox.m_fMinZ;
	if (m_fMaxZ < BoundingBox.m_fMaxZ) m_fMaxZ = BoundingBox.m_fMaxZ;
}

// Žæ“¾
float CBoundingBox::GetMinX() const
{
	return m_fMinX;
}

float CBoundingBox::GetMaxX() const
{
	return m_fMaxX;
}

float CBoundingBox::GetMinY() const
{
	return m_fMinY;
}

float CBoundingBox::GetMaxY() const
{
	return m_fMaxY;
}

float CBoundingBox::GetMinZ() const
{
	return m_fMinZ;
}

float CBoundingBox::GetMaxZ() const
{
	return m_fMaxZ;
}

float CBoundingBox::GetMaxLength() const
{
	return (std::max)((std::max)(m_fMaxX - m_fMinX, m_fMaxY - m_fMinY), m_fMaxZ - m_fMinZ);
}

S3D CBoundingBox::GetCenter() const
{
	return S3D((m_fMinX + m_fMaxX) * 0.5f, (m_fMinY + m_fMaxY) * 0.5f, (m_fMinZ + m_fMaxZ) * 0.5f);
}

S3D CBoundingBox::GetSize() const
{
	return S3D(m_fMaxX - m_fMinX, m_fMaxY - m_fMinY, m_fMaxZ - m_fMinZ);
}

float CBoundingBox::GetRadius() const
{
	return sqrtf(
		(m_fMaxX - m_fMinX) * (m_fMaxX - m_fMinX) +
		(m_fMaxY - m_fMinY) * (m_fMaxY - m_fMinY) +
		(m_fMaxZ - m_fMinZ) * (m_fMaxZ - m_fMinZ)) * 0.5f;
}

bool CBoundingBox::IsIn(const S3D& Pos) const
{
	return (
		Pos.fX >= m_fMinX && Pos.fX <= m_fMaxX &&
		Pos.fY >= m_fMinY && Pos.fY <= m_fMaxY &&
		Pos.fZ >= m_fMinZ && Pos.fZ <= m_fMaxZ);
}

}

