You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
6.9 KiB
288 lines
6.9 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "vbsp.h"
|
|
#include "BoundBox.h"
|
|
//#include "hammer_mathlib.h"
|
|
//#include "MapDefs.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
#if !defined(_MSC_VER) || _MSC_VER < 1800
|
|
// This C99 function exists in VS 2013's math.h but are not currently available elsewhere.
|
|
float rint(float f)
|
|
{
|
|
if (f > 0.0f) {
|
|
return (float) floor(f + 0.5f);
|
|
} else if (f < 0.0f) {
|
|
return (float) ceil(f - 0.5f);
|
|
} else
|
|
return 0.0f;
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
BoundBox::BoundBox(void)
|
|
{
|
|
ResetBounds();
|
|
}
|
|
|
|
BoundBox::BoundBox(const Vector &mins, const Vector &maxs)
|
|
{
|
|
bmins = mins;
|
|
bmaxs = maxs;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Sets the box to an uninitialized state, so that calls to UpdateBounds
|
|
// will properly set the mins and maxs.
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::ResetBounds(void)
|
|
{
|
|
bmins[0] = bmins[1] = bmins[2] = COORD_NOTINIT;
|
|
bmaxs[0] = bmaxs[1] = bmaxs[2] = -COORD_NOTINIT;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : pt -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::UpdateBounds(const Vector& pt)
|
|
{
|
|
if(pt[0] < bmins[0])
|
|
bmins[0] = pt[0];
|
|
if(pt[1] < bmins[1])
|
|
bmins[1] = pt[1];
|
|
if(pt[2] < bmins[2])
|
|
bmins[2] = pt[2];
|
|
|
|
if(pt[0] > bmaxs[0])
|
|
bmaxs[0] = pt[0];
|
|
if(pt[1] > bmaxs[1])
|
|
bmaxs[1] = pt[1];
|
|
if(pt[2] > bmaxs[2])
|
|
bmaxs[2] = pt[2];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : bmins -
|
|
// bmaxs -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::UpdateBounds(const Vector& mins, const Vector& maxs)
|
|
{
|
|
if(mins[0] < bmins[0])
|
|
bmins[0] = mins[0];
|
|
if(mins[1] < bmins[1])
|
|
bmins[1] = mins[1];
|
|
if(mins[2] < bmins[2])
|
|
bmins[2] = mins[2];
|
|
|
|
if(maxs[0] > bmaxs[0])
|
|
bmaxs[0] = maxs[0];
|
|
if(maxs[1] > bmaxs[1])
|
|
bmaxs[1] = maxs[1];
|
|
if(maxs[2] > bmaxs[2])
|
|
bmaxs[2] = maxs[2];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : pBox -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::UpdateBounds(const BoundBox *pBox)
|
|
{
|
|
UpdateBounds(pBox->bmins, pBox->bmaxs);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : ptdest -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::GetBoundsCenter(Vector& ptdest)
|
|
{
|
|
ptdest = (bmins + bmaxs)/2.0f;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : pt -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool BoundBox::ContainsPoint(const Vector& pt) const
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
if (pt[i] < bmins[i] || pt[i] > bmaxs[i])
|
|
{
|
|
return(false);
|
|
}
|
|
}
|
|
return(true);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : pfMins -
|
|
// pfMaxs -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool BoundBox::IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const
|
|
{
|
|
if ((bmins[0] >= pfMaxs[0]) || (bmaxs[0] <= pfMins[0]))
|
|
{
|
|
return(false);
|
|
|
|
}
|
|
if ((bmins[1] >= pfMaxs[1]) || (bmaxs[1] <= pfMins[1]))
|
|
{
|
|
return(false);
|
|
}
|
|
|
|
if ((bmins[2] >= pfMaxs[2]) || (bmaxs[2] <= pfMins[2]))
|
|
{
|
|
return(false);
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : pfMins -
|
|
// pfMaxs -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool BoundBox::IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const
|
|
{
|
|
if ((bmins[0] < pfMins[0]) || (bmaxs[0] > pfMaxs[0]))
|
|
{
|
|
return(false);
|
|
}
|
|
|
|
if ((bmins[1] < pfMins[1]) || (bmaxs[1] > pfMaxs[1]))
|
|
{
|
|
return(false);
|
|
}
|
|
|
|
if ((bmins[2] < pfMins[2]) || (bmaxs[2] > pfMaxs[2]))
|
|
{
|
|
return(false);
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Returns whether this bounding box is valid, ie maxs >= mins.
|
|
//-----------------------------------------------------------------------------
|
|
bool BoundBox::IsValidBox(void) const
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
if (bmins[i] > bmaxs[i])
|
|
{
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : size -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::GetBoundsSize(Vector& size)
|
|
{
|
|
size[0] = bmaxs[0] - bmins[0];
|
|
size[1] = bmaxs[1] - bmins[1];
|
|
size[2] = bmaxs[2] - bmins[2];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : iValue -
|
|
// iGridSize -
|
|
// Output :
|
|
//-----------------------------------------------------------------------------
|
|
static int Snap(/*int*/ float iValue, int iGridSize)
|
|
{
|
|
return (int)(rint(iValue/iGridSize) * iGridSize);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : iGridSize -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::SnapToGrid(int iGridSize)
|
|
{
|
|
// does not alter the size of the box .. snaps its minimal coordinates
|
|
// to the grid size specified in iGridSize
|
|
Vector size;
|
|
GetBoundsSize(size);
|
|
|
|
for(int i = 0; i < 3; i++)
|
|
{
|
|
bmins[i] = (float)Snap(/* YWB (int)*/bmins[i], iGridSize);
|
|
bmaxs[i] = bmins[i] + size[i];
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : axis -
|
|
//-----------------------------------------------------------------------------
|
|
void BoundBox::Rotate90(int axis)
|
|
{
|
|
int e1 = AXIS_X, e2 = AXIS_Y;
|
|
|
|
// get bounds center first
|
|
Vector center;
|
|
GetBoundsCenter(center);
|
|
|
|
switch(axis)
|
|
{
|
|
case AXIS_Z:
|
|
e1 = AXIS_X;
|
|
e2 = AXIS_Y;
|
|
break;
|
|
case AXIS_X:
|
|
e1 = AXIS_Y;
|
|
e2 = AXIS_Z;
|
|
break;
|
|
case AXIS_Y:
|
|
e1 = AXIS_X;
|
|
e2 = AXIS_Z;
|
|
break;
|
|
}
|
|
|
|
float tmp1, tmp2;
|
|
tmp1 = bmins[e1] - center[e1] + center[e2];
|
|
tmp2 = bmaxs[e1] - center[e1] + center[e2];
|
|
bmins[e1] = bmins[e2] - center[e2] + center[e1];
|
|
bmaxs[e1] = bmaxs[e2] - center[e2] + center[e1];
|
|
bmins[e2] = tmp1;
|
|
bmaxs[e2] = tmp2;
|
|
}
|
|
|